diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..db8786c --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..90aac4e --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/zyd2025.iml b/.idea/zyd2025.iml new file mode 100644 index 0000000..82a6846 --- /dev/null +++ b/.idea/zyd2025.iml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/README.md b/src/README.md index de1958f..5be71bf 100644 --- a/src/README.md +++ b/src/README.md @@ -146,7 +146,7 @@ python manage.py runserver ## 🙏 鸣谢 -特别感谢 **JetBrains** 为本项目提供的免费开源许可证。gs ls syj143 zyd164 +特别感谢 **JetBrains** 为本项目提供的免费开源许可证。gs ls syj zyd164

diff --git a/src/collectedstatic/CACHE/css/output.20f74afba408_with_comments.css b/src/collectedstatic/CACHE/css/output.20f74afba408_with_comments.css new file mode 100644 index 0000000..09587a8 --- /dev/null +++ b/src/collectedstatic/CACHE/css/output.20f74afba408_with_comments.css @@ -0,0 +1,688 @@ +/* + * 社交媒体图标样式 + */ + +/* Google 图标样式 */ +.icon-sn-google { + background-position: 0 -28px; +} + +.icon-sn-bg-google { + background-color: #4285f4; + background-position: 0 0; +} + +.fa-sn-google { + color: #4285f4; +} + +/* GitHub 图标样式 */ +.icon-sn-github { + background-position: -28px -28px; +} + +.icon-sn-bg-github { + background-color: #333; + background-position: -28px 0; +} + +.fa-sn-github { + color: #333; +} + +/* 微博图标样式 */ +.icon-sn-weibo { + background-position: -56px -28px; +} + +.icon-sn-bg-weibo { + background-color: #e90d24; + background-position: -56px 0; +} + +.fa-sn-weibo { + color: #e90d24; +} + +/* QQ 图标样式 */ +.icon-sn-qq { + background-position: -84px -28px; +} + +.icon-sn-bg-qq { + background-color: #0098e6; + background-position: -84px 0; +} + +.fa-sn-qq { + color: #0098e6; +} + +/* Twitter 图标样式 */ +.icon-sn-twitter { + background-position: -112px -28px; +} + +.icon-sn-bg-twitter { + background-color: #50abf1; + background-position: -112px 0; +} + +.fa-sn-twitter { + color: #50abf1; +} + +/* Facebook 图标样式 */ +.icon-sn-facebook { + background-position: -140px -28px; +} + +.icon-sn-bg-facebook { + background-color: #4862a3; + background-position: -140px 0; +} + +.fa-sn-facebook { + color: #4862a3; +} + +/* 人人网图标样式 */ +.icon-sn-renren { + background-position: -168px -28px; +} + +.icon-sn-bg-renren { + background-color: #197bc8; + background-position: -168px 0; +} + +.fa-sn-renren { + color: #197bc8; +} + +/* 腾讯微博图标样式 */ +.icon-sn-tqq { + background-position: -196px -28px; +} + +.icon-sn-bg-tqq { + background-color: #1f9ed2; + background-position: -196px 0; +} + +.fa-sn-tqq { + color: #1f9ed2; +} + +/* 豆瓣图标样式 */ +.icon-sn-douban { + background-position: -224px -28px; +} + +.icon-sn-bg-douban { + background-color: #279738; + background-position: -224px 0; +} + +.fa-sn-douban { + color: #279738; +} + +/* 微信图标样式 */ +.icon-sn-weixin { + background-position: -252px -28px; +} + +.icon-sn-bg-weixin { + background-color: #00b500; + background-position: -252px 0; +} + +.fa-sn-weixin { + color: #00b500; +} + +/* 虚线图标样式 */ +.icon-sn-dotted { + background-position: -280px -28px; +} + +.icon-sn-bg-dotted { + background-color: #eee; + background-position: -280px 0; +} + +.fa-sn-dotted { + color: #eee; +} + +/* 站点图标样式 */ +.icon-sn-site { + background-position: -308px -28px; +} + +.icon-sn-bg-site { + background-color: #00b500; + background-position: -308px 0; +} + +.fa-sn-site { + color: #00b500; +} + +/* LinkedIn 图标样式 */ +.icon-sn-linkedin { + background-position: -336px -28px; +} + +.icon-sn-bg-linkedin { + background-color: #0077b9; + background-position: -336px 0; +} + +.fa-sn-linkedin { + color: #0077b9; +} + +/* 通用图标样式 */ +[class*=icon-sn-] { + display: inline-block; + background-image: url('/static/blog/img/icon-sn.svg?56272f05e520'); + background-repeat: no-repeat; + width: 28px; + height: 28px; + vertical-align: middle; + background-size: auto 56px; +} + +[class*=icon-sn-]:hover { + opacity: .8; + filter: alpha(opacity=80); +} + +/* + * 社交媒体按钮样式 + */ + +/* Google 按钮样式 */ +.btn-sn-google { + background: #4285f4; +} + +.btn-sn-google:active, +.btn-sn-google:focus, +.btn-sn-google:hover { + background: #2a75f3; +} + +/* GitHub 按钮样式 */ +.btn-sn-github { + background: #333; +} + +.btn-sn-github:active, +.btn-sn-github:focus, +.btn-sn-github:hover { + background: #262626; +} + +/* 微博按钮样式 */ +.btn-sn-weibo { + background: #e90d24; +} + +.btn-sn-weibo:active, +.btn-sn-weibo:focus, +.btn-sn-weibo:hover { + background: #d10c20; +} + +/* QQ 按钮样式 */ +.btn-sn-qq { + background: #0098e6; +} + +.btn-sn-qq:active, +.btn-sn-qq:focus, +.btn-sn-qq:hover { + background: #0087cd; +} + +/* Twitter 按钮样式 */ +.btn-sn-twitter { + background: #50abf1; +} + +.btn-sn-twitter:active, +.btn-sn-twitter:focus, +.btn-sn-twitter:hover { + background: #38a0ef; +} + +/* Facebook 按钮样式 */ +.btn-sn-facebook { + background: #4862a3; +} + +.btn-sn-facebook:active, +.btn-sn-facebook:focus, +.btn-sn-facebook:hover { + background: #405791; +} + +/* 人人网按钮样式 */ +.btn-sn-renren { + background: #197bc8; +} + +.btn-sn-renren:active, +.btn-sn-renren:focus, +.btn-sn-renren:hover { + background: #166db1; +} + +/* 腾讯微博按钮样式 */ +.btn-sn-tqq { + background: #1f9ed2; +} + +.btn-sn-tqq:active, +.btn-sn-tqq:focus, +.btn-sn-tqq:hover { + background: #1c8dbc; +} + +/* 豆瓣按钮样式 */ +.btn-sn-douban { + background: #279738; +} + +.btn-sn-douban:active, +.btn-sn-douban:focus, +.btn-sn-douban:hover { + background: #228330; +} + +/* 微信按钮样式 */ +.btn-sn-weixin { + background: #00b500; +} + +.btn-sn-weixin:active, +.btn-sn-weixin:focus, +.btn-sn-weixin:hover { + background: #009c00; +} + +/* 虚线按钮样式 */ +.btn-sn-dotted { + background: #eee; +} + +.btn-sn-dotted:active, +.btn-sn-dotted:focus, +.btn-sn-dotted:hover { + background: #e1e1e1; +} + +/* 站点按钮样式 */ +.btn-sn-site { + background: #00b500; +} + +.btn-sn-site:active, +.btn-sn-site:focus, +.btn-sn-site:hover { + background: #009c00; +} + +/* LinkedIn 按钮样式 */ +.btn-sn-linkedin { + background: #0077b9; +} + +.btn-sn-linkedin:active, +.btn-sn-linkedin:focus, +.btn-sn-linkedin:hover { + background: #0067a0; +} + +/* 通用按钮样式 */ +[class*=btn-sn-], +[class*=btn-sn-]:active, +[class*=btn-sn-]:focus, +[class*=btn-sn-]:hover { + border: none; + color: #fff; +} + +.btn-sn-more { + padding: 0; +} + +.btn-sn-more, +.btn-sn-more:active, +.btn-sn-more:hover { + box-shadow: none; +} + +[class*=btn-sn-] [class*=icon-sn-] { + background-color: transparent; +} + +/* + * 代码高亮样式 + */ +.codehilite .hll { + background-color: #ffffcc; +} + +.codehilite { + background: #ffffff; +} + +.codehilite .c { + color: #177500; +} + +.codehilite .err { + color: #000000; +} + +.codehilite .k { + color: #A90D91; +} + +.codehilite .l { + color: #1C01CE; +} + +.codehilite .n { + color: #000000; +} + +.codehilite .o { + color: #000000; +} + +.codehilite .ch { + color: #177500; +} + +.codehilite .cm { + color: #177500; +} + +.codehilite .cp { + color: #633820; +} + +.codehilite .cpf { + color: #177500; +} + +.codehilite .c1 { + color: #177500; +} + +.codehilite .cs { + color: #177500; +} + +.codehilite .kc { + color: #A90D91; +} + +.codehilite .kd { + color: #A90D91; +} + +.codehilite .kn { + color: #A90D91; +} + +.codehilite .kp { + color: #A90D91; +} + +.codehilite .kr { + color: #A90D91; +} + +.codehilite .kt { + color: #A90D91; +} + +.codehilite .ld { + color: #1C01CE; +} + +.codehilite .m { + color: #1C01CE; +} + +.codehilite .s { + color: #C41A16; +} + +.codehilite .na { + color: #836C28; +} + +.codehilite .nb { + color: #A90D91; +} + +.codehilite .nc { + color: #3F6E75; +} + +.codehilite .no { + color: #000000; +} + +.codehilite .nd { + color: #000000; +} + +.codehilite .ni { + color: #000000; +} + +.codehilite .ne { + color: #000000; +} + +.codehilite .nf { + color: #000000; +} + +.codehilite .nl { + color: #000000; +} + +.codehilite .nn { + color: #000000; +} + +.codehilite .nx { + color: #000000; +} + +.codehilite .py { + color: #000000; +} + +.codehilite .nt { + color: #000000; +} + +.codehilite .nv { + color: #000000; +} + +.codehilite .ow { + color: #000000; +} + +.codehilite .mb { + color: #1C01CE; +} + +.codehilite .mf { + color: #1C01CE; +} + +.codehilite .mh { + color: #1C01CE; +} + +.codehilite .mi { + color: #1C01CE; +} + +.codehilite .mo { + color: #1C01CE; +} + +.codehilite .sb { + color: #C41A16; +} + +.codehilite .sc { + color: #2300CE; +} + +.codehilite .sd { + color: #C41A16; +} + +.codehilite .s2 { + color: #C41A16; +} + +.codehilite .se { + color: #C41A16; +} + +.codehilite .sh { + color: #C41A16; +} + +.codehilite .si { + color: #C41A16; +} + +.codehilite .sx { + color: #C41A16; +} + +.codehilite .sr { + color: #C41A16; +} + +.codehilite .s1 { + color: #C41A16; +} + +.codehilite .ss { + color: #C41A16; +} + +.codehilite .bp { + color: #5B269A; +} + +.codehilite .vc { + color: #000000; +} + +.codehilite .vg { + color: #000000; +} + +.codehilite .vi { + color: #000000; +} + +.codehilite .il { + color: #1C01CE; +} + +/* + * 进度条样式 (NProgress) + */ +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: red; + position: fixed; + z-index: 1031; + top: 0; + left: 0; + width: 100%; + height: 2px; +} + +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: 0 0 10px #29d, 0 0 5px #29d; + opacity: 1.0; + -webkit-transform: rotate(3deg) translate(0px, -4px); + -ms-transform: rotate(3deg) translate(0px, -4px); + transform: rotate(3deg) translate(0px, -4px); +} + +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + border: solid 2px transparent; + border-top-color: red; + border-left-color: red; + border-radius: 50%; + -webkit-animation: nprogress-spinner 400ms linear infinite; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@-webkit-keyframes nprogress-spinner { + 0% { + -webkit-transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + } +} + +@keyframes nprogress-spinner { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} \ No newline at end of file diff --git a/src/collectedstatic/CACHE/css/output.5ee9ff3cb1a7_with_comments.css b/src/collectedstatic/CACHE/css/output.5ee9ff3cb1a7_with_comments.css new file mode 100644 index 0000000..c3a74e4 --- /dev/null +++ b/src/collectedstatic/CACHE/css/output.5ee9ff3cb1a7_with_comments.css @@ -0,0 +1,1846 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ + +/* + * HTML5显示定义 + * 正确显示HTML5新增元素 + */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + margin: 0; +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +[hidden], +template { + display: none; +} + +/* + * 链接样式 + */ +a { + background-color: transparent; +} + +a:active, +a:hover { + outline: 0; +} + +/* + * 文本样式 + */ +abbr[title] { + border-bottom: 1px dotted; +} + +b, +strong { + font-weight: bold; +} + +dfn { + font-style: italic; +} + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +mark { + background: #ff0; + color: #000; +} + +small { + font-size: 80%; +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* + * 嵌入内容样式 + */ +img { + border: 0; +} + +svg:not(:root) { + overflow: hidden; +} + +/* + * 图片和表格样式 + */ +figure { + margin: 1em 40px; +} + +hr { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +pre { + overflow: auto; +} + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* + * 表单样式 + */ +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0; +} + +button { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} + +button[disabled], +html input[disabled] { + cursor: default; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +input { + line-height: normal; +} + +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +input[type="search"] { + -webkit-appearance: textfield; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +legend { + border: 0; + padding: 0; +} + +textarea { + overflow: auto; +} + +optgroup { + font-weight: bold; +} + +/* + * 表格样式 + */ +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} + +/* + * 打印样式 + */ +@media print { + *, + *:before, + *:after { + background: transparent !important; + color: #000 !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + text-shadow: none !important; + } + + a, + a:visited { + text-decoration: underline; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + thead { + display: table-header-group; + } + + tr, + img { + page-break-inside: avoid; + } + + img { + max-width: 100% !important; + } + + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + + h2, + h3 { + page-break-after: avoid; + } + + .navbar { + display: none; + } + + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + + .label { + border: 1px solid #000; + } + + .table { + border-collapse: collapse !important; + } + + .table td, + .table th { + background-color: #fff !important; + } + + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} + +/* + * Glyphicons 字体图标 + */ +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), + url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), + url('../fonts/glyphicons-halflings-regular.woff') format('woff'), + url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), + url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} + +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* + * Glyphicons 图标定义 + */ +.glyphicon-asterisk:before { + content: "\002a"; +} + +.glyphicon-plus:before { + content: "\002b"; +} + +.glyphicon-eur:before, +.glyphicon-euro:before { + content: "\20ac"; +} + +.glyphicon-minus:before { + content: "\2212"; +} + +.glyphicon-cloud:before { + content: "\2601"; +} + +.glyphicon-envelope:before { + content: "\2709"; +} + +.glyphicon-pencil:before { + content: "\270f"; +} + +.glyphicon-glass:before { + content: "\e001"; +} + +.glyphicon-music:before { + content: "\e002"; +} + +.glyphicon-search:before { + content: "\e003"; +} + +.glyphicon-heart:before { + content: "\e005"; +} + +.glyphicon-star:before { + content: "\e006"; +} + +.glyphicon-star-empty:before { + content: "\e007"; +} + +.glyphicon-user:before { + content: "\e008"; +} + +.glyphicon-film:before { + content: "\e009"; +} + +.glyphicon-th-large:before { + content: "\e010"; +} + +.glyphicon-th:before { + content: "\e011"; +} + +.glyphicon-th-list:before { + content: "\e012"; +} + +.glyphicon-ok:before { + content: "\e013"; +} + +.glyphicon-remove:before { + content: "\e014"; +} + +.glyphicon-zoom-in:before { + content: "\e015"; +} + +.glyphicon-zoom-out:before { + content: "\e016"; +} + +.glyphicon-off:before { + content: "\e017"; +} + +.glyphicon-signal:before { + content: "\e018"; +} + +.glyphicon-cog:before { + content: "\e019"; +} + +.glyphicon-trash:before { + content: "\e020"; +} + +.glyphicon-home:before { + content: "\e021"; +} + +.glyphicon-file:before { + content: "\e022"; +} + +.glyphicon-time:before { + content: "\e023"; +} + +.glyphicon-road:before { + content: "\e024"; +} + +.glyphicon-download-alt:before { + content: "\e025"; +} + +.glyphicon-download:before { + content: "\e026"; +} + +.glyphicon-upload:before { + content: "\e027"; +} + +.glyphicon-inbox:before { + content: "\e028"; +} + +.glyphicon-play-circle:before { + content: "\e029"; +} + +.glyphicon-repeat:before { + content: "\e030"; +} + +.glyphicon-refresh:before { + content: "\e031"; +} + +.glyphicon-list-alt:before { + content: "\e032"; +} + +.glyphicon-lock:before { + content: "\e033"; +} + +.glyphicon-flag:before { + content: "\e034"; +} + +.glyphicon-headphones:before { + content: "\e035"; +} + +.glyphicon-volume-off:before { + content: "\e036"; +} + +.glyphicon-volume-down:before { + content: "\e037"; +} + +.glyphicon-volume-up:before { + content: "\e038"; +} + +.glyphicon-qrcode:before { + content: "\e039"; +} + +.glyphicon-barcode:before { + content: "\e040"; +} + +.glyphicon-tag:before { + content: "\e041"; +} + +.glyphicon-tags:before { + content: "\e042"; +} + +.glyphicon-book:before { + content: "\e043"; +} + +.glyphicon-bookmark:before { + content: "\e044"; +} + +.glyphicon-print:before { + content: "\e045"; +} + +.glyphicon-camera:before { + content: "\e046"; +} + +.glyphicon-font:before { + content: "\e047"; +} + +.glyphicon-bold:before { + content: "\e048"; +} + +.glyphicon-italic:before { + content: "\e049"; +} + +.glyphicon-text-height:before { + content: "\e050"; +} + +.glyphicon-text-width:before { + content: "\e051"; +} + +.glyphicon-align-left:before { + content: "\e052"; +} + +.glyphicon-align-center:before { + content: "\e053"; +} + +.glyphicon-align-right:before { + content: "\e054"; +} + +.glyphicon-align-justify:before { + content: "\e055"; +} + +.glyphicon-list:before { + content: "\e056"; +} + +.glyphicon-indent-left:before { + content: "\e057"; +} + +.glyphicon-indent-right:before { + content: "\e058"; +} + +.glyphicon-facetime-video:before { + content: "\e059"; +} + +.glyphicon-picture:before { + content: "\e060"; +} + +.glyphicon-map-marker:before { + content: "\e062"; +} + +.glyphicon-adjust:before { + content: "\e063"; +} + +.glyphicon-tint:before { + content: "\e064"; +} + +.glyphicon-edit:before { + content: "\e065"; +} + +.glyphicon-share:before { + content: "\e066"; +} + +.glyphicon-check:before { + content: "\e067"; +} + +.glyphicon-move:before { + content: "\e068"; +} + +.glyphicon-step-backward:before { + content: "\e069"; +} + +.glyphicon-fast-backward:before { + content: "\e070"; +} + +.glyphicon-backward:before { + content: "\e071"; +} + +.glyphicon-play:before { + content: "\e072"; +} + +.glyphicon-pause:before { + content: "\e073"; +} + +.glyphicon-stop:before { + content: "\e074"; +} + +.glyphicon-forward:before { + content: "\e075"; +} + +.glyphicon-fast-forward:before { + content: "\e076"; +} + +.glyphicon-step-forward:before { + content: "\e077"; +} + +.glyphicon-eject:before { + content: "\e078"; +} + +.glyphicon-chevron-left:before { + content: "\e079"; +} + +.glyphicon-chevron-right:before { + content: "\e080"; +} + +.glyphicon-plus-sign:before { + content: "\e081"; +} + +.glyphicon-minus-sign:before { + content: "\e082"; +} + +.glyphicon-remove-sign:before { + content: "\e083"; +} + +.glyphicon-ok-sign:before { + content: "\e084"; +} + +.glyphicon-question-sign:before { + content: "\e085"; +} + +.glyphicon-info-sign:before { + content: "\e086"; +} + +.glyphicon-screenshot:before { + content: "\e087"; +} + +.glyphicon-remove-circle:before { + content: "\e088"; +} + +.glyphicon-ok-circle:before { + content: "\e089"; +} + +.glyphicon-ban-circle:before { + content: "\e090"; +} + +.glyphicon-arrow-left:before { + content: "\e091"; +} + +.glyphicon-arrow-right:before { + content: "\e092"; +} + +.glyphicon-arrow-up:before { + content: "\e093"; +} + +.glyphicon-arrow-down:before { + content: "\e094"; +} + +.glyphicon-share-alt:before { + content: "\e095"; +} + +.glyphicon-resize-full:before { + content: "\e096"; +} + +.glyphicon-resize-small:before { + content: "\e097"; +} + +.glyphicon-exclamation-sign:before { + content: "\e101"; +} + +.glyphicon-gift:before { + content: "\e102"; +} + +.glyphicon-leaf:before { + content: "\e103"; +} + +.glyphicon-fire:before { + content: "\e104"; +} + +.glyphicon-eye-open:before { + content: "\e105"; +} + +.glyphicon-eye-close:before { + content: "\e106"; +} + +.glyphicon-warning-sign:before { + content: "\e107"; +} + +.glyphicon-plane:before { + content: "\e108"; +} + +.glyphicon-calendar:before { + content: "\e109"; +} + +.glyphicon-random:before { + content: "\e110"; +} + +.glyphicon-comment:before { + content: "\e111"; +} + +.glyphicon-magnet:before { + content: "\e112"; +} + +.glyphicon-chevron-up:before { + content: "\e113"; +} + +.glyphicon-chevron-down:before { + content: "\e114"; +} + +.glyphicon-retweet:before { + content: "\e115"; +} + +.glyphicon-shopping-cart:before { + content: "\e116"; +} + +.glyphicon-folder-close:before { + content: "\e117"; +} + +.glyphicon-folder-open:before { + content: "\e118"; +} + +.glyphicon-resize-vertical:before { + content: "\e119"; +} + +.glyphicon-resize-horizontal:before { + content: "\e120"; +} + +.glyphicon-hdd:before { + content: "\e121"; +} + +.glyphicon-bullhorn:before { + content: "\e122"; +} + +.glyphicon-bell:before { + content: "\e123"; +} + +.glyphicon-certificate:before { + content: "\e124"; +} + +.glyphicon-thumbs-up:before { + content: "\e125"; +} + +.glyphicon-thumbs-down:before { + content: "\e126"; +} + +.glyphicon-hand-right:before { + content: "\e127"; +} + +.glyphicon-hand-left:before { + content: "\e128"; +} + +.glyphicon-hand-up:before { + content: "\e129"; +} + +.glyphicon-hand-down:before { + content: "\e130"; +} + +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} + +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} + +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} + +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} + +.glyphicon-globe:before { + content: "\e135"; +} + +.glyphicon-wrench:before { + content: "\e136"; +} + +.glyphicon-tasks:before { + content: "\e137"; +} + +.glyphicon-filter:before { + content: "\e138"; +} + +.glyphicon-briefcase:before { + content: "\e139"; +} + +.glyphicon-fullscreen:before { + content: "\e140"; +} + +.glyphicon-dashboard:before { + content: "\e141"; +} + +.glyphicon-paperclip:before { + content: "\e142"; +} + +.glyphicon-heart-empty:before { + content: "\e143"; +} + +.glyphicon-link:before { + content: "\e144"; +} + +.glyphicon-phone:before { + content: "\e145"; +} + +.glyphicon-pushpin:before { + content: "\e146"; +} + +.glyphicon-usd:before { + content: "\e148"; +} + +.glyphicon-gbp:before { + content: "\e149"; +} + +.glyphicon-sort:before { + content: "\e150"; +} + +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} + +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} + +.glyphicon-sort-by-order:before { + content: "\e153"; +} + +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} + +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} + +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} + +.glyphicon-unchecked:before { + content: "\e157"; +} + +.glyphicon-expand:before { + content: "\e158"; +} + +.glyphicon-collapse-down:before { + content: "\e159"; +} + +.glyphicon-collapse-up:before { + content: "\e160"; +} + +.glyphicon-log-in:before { + content: "\e161"; +} + +.glyphicon-flash:before { + content: "\e162"; +} + +.glyphicon-log-out:before { + content: "\e163"; +} + +.glyphicon-new-window:before { + content: "\e164"; +} + +.glyphicon-record:before { + content: "\e165"; +} + +.glyphicon-save:before { + content: "\e166"; +} + +.glyphicon-open:before { + content: "\e167"; +} + +.glyphicon-saved:before { + content: "\e168"; +} + +.glyphicon-import:before { + content: "\e169"; +} + +.glyphicon-export:before { + content: "\e170"; +} + +.glyphicon-send:before { + content: "\e171"; +} + +.glyphicon-floppy-disk:before { + content: "\e172"; +} + +.glyphicon-floppy-saved:before { + content: "\e173"; +} + +.glyphicon-floppy-remove:before { + content: "\e174"; +} + +.glyphicon-floppy-save:before { + content: "\e175"; +} + +.glyphicon-floppy-open:before { + content: "\e176"; +} + +.glyphicon-credit-card:before { + content: "\e177"; +} + +.glyphicon-transfer:before { + content: "\e178"; +} + +.glyphicon-cutlery:before { + content: "\e179"; +} + +.glyphicon-header:before { + content: "\e180"; +} + +.glyphicon-compressed:before { + content: "\e181"; +} + +.glyphicon-earphone:before { + content: "\e182"; +} + +.glyphicon-phone-alt:before { + content: "\e183"; +} + +.glyphicon-tower:before { + content: "\e184"; +} + +.glyphicon-stats:before { + content: "\e185"; +} + +.glyphicon-sd-video:before { + content: "\e186"; +} + +.glyphicon-hd-video:before { + content: "\e187"; +} + +.glyphicon-subtitles:before { + content: "\e188"; +} + +.glyphicon-sound-stereo:before { + content: "\e189"; +} + +.glyphicon-sound-dolby:before { + content: "\e190"; +} + +.glyphicon-sound-5-1:before { + content: "\e191"; +} + +.glyphicon-sound-6-1:before { + content: "\e192"; +} + +.glyphicon-sound-7-1:before { + content: "\e193"; +} + +.glyphicon-copyright-mark:before { + content: "\e194"; +} + +.glyphicon-registration-mark:before { + content: "\e195"; +} + +.glyphicon-cloud-download:before { + content: "\e197"; +} + +.glyphicon-cloud-upload:before { + content: "\e198"; +} + +.glyphicon-tree-conifer:before { + content: "\e199"; +} + +.glyphicon-tree-deciduous:before { + content: "\e200"; +} + +.glyphicon-cd:before { + content: "\e201"; +} + +.glyphicon-save-file:before { + content: "\e202"; +} + +.glyphicon-open-file:before { + content: "\e203"; +} + +.glyphicon-level-up:before { + content: "\e204"; +} + +.glyphicon-copy:before { + content: "\e205"; +} + +.glyphicon-paste:before { + content: "\e206"; +} + +.glyphicon-alert:before { + content: "\e209"; +} + +.glyphicon-equalizer:before { + content: "\e210"; +} + +.glyphicon-king:before { + content: "\e211"; +} + +.glyphicon-queen:before { + content: "\e212"; +} + +.glyphicon-pawn:before { + content: "\e213"; +} + +.glyphicon-bishop:before { + content: "\e214"; +} + +.glyphicon-knight:before { + content: "\e215"; +} + +.glyphicon-baby-formula:before { + content: "\e216"; +} + +.glyphicon-tent:before { + content: "\26fa"; +} + +.glyphicon-blackboard:before { + content: "\e218"; +} + +.glyphicon-bed:before { + content: "\e219"; +} + +.glyphicon-apple:before { + content: "\f8ff"; +} + +.glyphicon-erase:before { + content: "\e221"; +} + +.glyphicon-hourglass:before { + content: "\231b"; +} + +.glyphicon-lamp:before { + content: "\e223"; +} + +.glyphicon-duplicate:before { + content: "\e224"; +} + +.glyphicon-piggy-bank:before { + content: "\e225"; +} + +.glyphicon-scissors:before { + content: "\e226"; +} + +.glyphicon-bitcoin:before { + content: "\e227"; +} + +.glyphicon-btc:before { + content: "\e227"; +} + +.glyphicon-xbt:before { + content: "\e227"; +} + +.glyphicon-yen:before { + content: "\00a5"; +} + +.glyphicon-jpy:before { + content: "\00a5"; +} + +.glyphicon-ruble:before { + content: "\20bd"; +} + +.glyphicon-rub:before { + content: "\20bd"; +} + +.glyphicon-scale:before { + content: "\e230"; +} + +.glyphicon-ice-lolly:before { + content: "\e231"; +} + +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} + +.glyphicon-education:before { + content: "\e233"; +} + +.glyphicon-option-horizontal:before { + content: "\e234"; +} + +.glyphicon-option-vertical:before { + content: "\e235"; +} + +.glyphicon-menu-hamburger:before { + content: "\e236"; +} + +.glyphicon-modal-window:before { + content: "\e237"; +} + +.glyphicon-oil:before { + content: "\e238"; +} + +.glyphicon-grain:before { + content: "\e239"; +} + +.glyphicon-sunglasses:before { + content: "\e240"; +} + +.glyphicon-text-size:before { + content: "\e241"; +} + +.glyphicon-text-color:before { + content: "\e242"; +} + +.glyphicon-text-background:before { + content: "\e243"; +} + +.glyphicon-object-align-top:before { + content: "\e244"; +} + +.glyphicon-object-align-bottom:before { + content: "\e245"; +} + +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} + +.glyphicon-object-align-left:before { + content: "\e247"; +} + +.glyphicon-object-align-vertical:before { + content: "\e248"; +} + +.glyphicon-object-align-right:before { + content: "\e249"; +} + +.glyphicon-triangle-right:before { + content: "\e250"; +} + +.glyphicon-triangle-left:before { + content: "\e251"; +} + +.glyphicon-triangle-bottom:before { + content: "\e252"; +} + +.glyphicon-triangle-top:before { + content: "\e253"; +} + +.glyphicon-console:before { + content: "\e254"; +} + +.glyphicon-superscript:before { + content: "\e255"; +} + +.glyphicon-subscript:before { + content: "\e256"; +} + +.glyphicon-menu-left:before { + content: "\e257"; +} + +.glyphicon-menu-right:before { + content: "\e258"; +} + +.glyphicon-menu-down:before { + content: "\e259"; +} + +.glyphicon-menu-up:before { + content: "\e260"; +} + +/* + * 布局样式 + */ +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +html { + font-size: 10px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} + +/* + * 链接样式 + */ +a { + color: #337ab7; + text-decoration: none; +} + +a:hover, +a:focus { + color: #23527c; + text-decoration: underline; +} + +a:focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +/* + * 图片样式 + */ +img { + vertical-align: middle; +} + +.img-responsive { + display: block; + max-width: 100%; + height: auto; +} + +.img-rounded { + border-radius: 6px; +} + +.img-thumbnail { + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + display: inline-block; + max-width: 100%; + height: auto; +} + +.img-circle { + border-radius: 50%; +} + +/* + * 表格样式 + */ +table { + background-color: transparent; +} + +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777; + text-align: left; +} + +th { + text-align: left; +} + +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} + +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} + +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} + +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} + +.table > tbody + tbody { + border-top: 2px solid #ddd; +} + +.table .table { + background-color: #fff; +} + +/* + * 表单样式 + */ +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + 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, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s; + -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} + +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); +} + +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} + +.form-control:-ms-input-placeholder { + color: #999; +} + +.form-control::-webkit-input-placeholder { + color: #999; +} + +/* + * 按钮样式 + */ +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn:hover, +.btn:focus, +.btn.focus { + color: #333; + text-decoration: none; +} + +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} + +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + filter: alpha(opacity=65); + opacity: 0.65; + -webkit-box-shadow: none; + box-shadow: none; +} + +/* + * 导航样式 + */ +.nav { + margin-bottom: 0; + padding-left: 0; + list-style: none; +} + +.nav > li { + position: relative; + display: block; +} + +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} + +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} + +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #337ab7; +} + +.nav-tabs { + border-bottom: 1px solid #ddd; +} + +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} + +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} + +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} + +/* + * 导航栏样式 + */ +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} + +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} + +.navbar-brand { + float: left; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; + height: 50px; +} + +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} + +.navbar-nav { + margin: 7.5px -15px; +} + +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} + +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + + .navbar-nav > li { + float: left; + } + + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} + +/* + * 面板样式 + */ +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.panel-body { + padding: 15px; +} + +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} + +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} + +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} + +/* + * 响应式工具类 + */ +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} + +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} + +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} + +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} \ No newline at end of file diff --git a/src/collectedstatic/account/css/account.css b/src/collectedstatic/account/css/account.css index 7d4cec7..1ecf43b 100644 --- a/src/collectedstatic/account/css/account.css +++ b/src/collectedstatic/account/css/account.css @@ -1,9 +1,25 @@ +/* 按钮样式 */ +/* Button styles */ .button { + /* 移除边框 */ + /* Remove border */ border: none; + /* 设置内边距 */ + /* Set padding */ padding: 4px 80px; + /* 设置文本对齐方式 */ + /* Set text alignment */ text-align: center; + /* 移除文本装饰 */ + /* Remove text decoration */ text-decoration: none; + /* 设置为行内块元素 */ + /* Set as inline-block element */ display: inline-block; + /* 设置字体大小 */ + /* Set font size */ font-size: 16px; + /* 设置外边距 */ + /* Set margin */ margin: 4px 2px; } \ No newline at end of file diff --git a/src/collectedstatic/account/js/account.js b/src/collectedstatic/account/js/account.js index f1a8771..08ae52f 100644 --- a/src/collectedstatic/account/js/account.js +++ b/src/collectedstatic/account/js/account.js @@ -1,15 +1,35 @@ +// 设置倒计时初始值为60秒 +// Set initial countdown value to 60 seconds let wait = 60; +// 倒计时函数,用于在发送验证码按钮上显示倒计时 +// Countdown function to display countdown on the send verification code button function time(o) { + // 如果倒计时结束 + // If countdown is over if (wait == 0) { + // 移除按钮的禁用状态 + // Remove button disabled state o.removeAttribute("disabled"); + // 恢复按钮文本 + // Restore button text o.value = "获取验证码"; + // 重置倒计时 + // Reset countdown wait = 60 return false } else { + // 设置按钮为禁用状态 + // Set button to disabled state o.setAttribute("disabled", true); + // 更新按钮文本显示倒计时 + // Update button text to show countdown o.value = "重新发送(" + wait + ")"; + // 倒计时减1 + // Decrease countdown by 1 wait--; + // 1秒后递归调用此函数 + // Recursively call this function after 1 second setTimeout(function () { time(o) }, @@ -17,31 +37,65 @@ function time(o) { } } +// 获取验证码按钮点击事件处理 +// Verification code button click event handler document.getElementById("btn").onclick = function () { + // 获取邮箱输入框元素 + // Get email input element let id_email = $("#id_email") + // 获取CSRF令牌 + // Get CSRF token let token = $("*[name='csrfmiddlewaretoken']").val() + // 获取当前按钮元素 + // Get current button element let ts = this + // 获取错误信息显示元素 + // Get error message display element let myErr = $("#myErr") + // 发送AJAX请求 + // Send AJAX request $.ajax( { + // 请求URL + // Request URL url: "/forget_password_code/", + // 请求类型 + // Request type type: "POST", + // 请求数据 + // Request data data: { "email": id_email.val(), "csrfmiddlewaretoken": token }, + // 请求成功回调函数 + // Success callback function success: function (result) { + // 如果返回结果不是"ok" + // If the returned result is not "ok" if (result != "ok") { + // 移除旧的错误信息 + // Remove old error message myErr.remove() + // 在邮箱输入框后添加新的错误信息 + // Add new error message after email input id_email.after("

") return } + // 移除错误信息 + // Remove error message myErr.remove() + // 启动倒计时 + // Start countdown time(ts) }, + // 请求失败回调函数 + // Error callback function error: function (e) { + // 弹出发送失败提示 + // Show send failure alert alert("发送失败,请重试") } } ); -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/autocomplete.css b/src/collectedstatic/admin/css/autocomplete.css index 7478c2c..ef87959 100644 --- a/src/collectedstatic/admin/css/autocomplete.css +++ b/src/collectedstatic/admin/css/autocomplete.css @@ -1,54 +1,68 @@ +/* 管理界面自动补全样式 */ +/* Admin autocomplete styles */ + +/* 选择器宽度设置 */ select.admin-autocomplete { width: 20em; } +/* 自动补全容器最小高度设置 */ .select2-container--admin-autocomplete.select2-container { min-height: 30px; } +/* 单选和多选容器最小高度设置 */ .select2-container--admin-autocomplete .select2-selection--single, .select2-container--admin-autocomplete .select2-selection--multiple { min-height: 30px; padding: 0; } +/* 聚焦或打开状态下的选择器边框颜色 */ .select2-container--admin-autocomplete.select2-container--focus .select2-selection, .select2-container--admin-autocomplete.select2-container--open .select2-selection { border-color: var(--body-quiet-color); min-height: 30px; } +/* 聚焦或打开状态下单选选择器内边距 */ .select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--single, .select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--single { padding: 0; } +/* 聚焦或打开状态下多选选择器内边距 */ .select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--multiple, .select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--multiple { padding: 0; } +/* 单选选择器背景、边框和圆角设置 */ .select2-container--admin-autocomplete .select2-selection--single { background-color: var(--body-bg); border: 1px solid var(--border-color); border-radius: 4px; } +/* 单选选择器渲染内容颜色和行高设置 */ .select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered { color: var(--body-fg); line-height: 30px; } +/* 单选选择器清除按钮光标和浮动设置 */ .select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; } +/* 单选选择器占位符颜色设置 */ .select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder { color: var(--body-quiet-color); } +/* 单选选择器箭头高度、位置和宽度设置 */ .select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow { height: 26px; position: absolute; @@ -57,6 +71,7 @@ select.admin-autocomplete { width: 20px; } +/* 单选选择器箭头图标样式设置 */ .select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow b { border-color: #888 transparent transparent transparent; border-style: solid; @@ -70,29 +85,35 @@ select.admin-autocomplete { width: 0; } +/* 从右到左语言环境下单选选择器清除按钮浮动设置 */ .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__clear { float: left; } +/* 从右到左语言环境下单选选择器箭头位置设置 */ .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__arrow { left: 1px; right: auto; } +/* 禁用状态下单选选择器背景和光标设置 */ .select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single { background-color: var(--darkened-bg); cursor: default; } +/* 禁用状态下单选选择器清除按钮显示设置 */ .select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single .select2-selection__clear { display: none; } +/* 打开状态下单选选择器箭头图标样式设置 */ .select2-container--admin-autocomplete.select2-container--open .select2-selection--single .select2-selection__arrow b { border-color: transparent transparent #888 transparent; border-width: 0 4px 5px 4px; } +/* 多选选择器背景、边框、圆角和光标设置 */ .select2-container--admin-autocomplete .select2-selection--multiple { background-color: var(--body-bg); border: 1px solid var(--border-color); @@ -100,6 +121,7 @@ select.admin-autocomplete { cursor: text; } +/* 多选选择器渲染内容盒模型、列表样式、外边距、内边距和宽度设置 */ .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered { box-sizing: border-box; list-style: none; @@ -110,16 +132,19 @@ select.admin-autocomplete { flex-wrap: wrap; } +/* 多选选择器渲染内容列表项样式设置 */ .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li { list-style: none; } +/* 多选选择器占位符颜色、上外边距和浮动设置 */ .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder { color: var(--body-quiet-color); margin-top: 5px; float: left; } +/* 多选选择器清除按钮光标、浮动、字体粗细、外边距、位置和右边距设置 */ .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear { cursor: pointer; float: right; @@ -129,6 +154,7 @@ select.admin-autocomplete { right: 0; } +/* 多选选择器选项背景、边框、圆角、光标、浮动、右边距、上外边距和内边距设置 */ .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice { background-color: var(--darkened-bg); border: 1px solid var(--border-color); @@ -140,6 +166,7 @@ select.admin-autocomplete { padding: 0 5px; } +/* 多选选择器选项移除按钮颜色、光标、显示、字体粗细和右边距设置 */ .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove { color: var(--body-quiet-color); cursor: pointer; @@ -148,52 +175,63 @@ select.admin-autocomplete { margin-right: 2px; } +/* 多选选择器选项移除按钮悬停状态颜色设置 */ .select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover { color: var(--body-fg); } +/* 从右到左语言环境下多选选择器选项、占位符和内联搜索浮动设置 */ .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-search--inline { float: right; } +/* 从右到左语言环境下多选选择器选项左边距和右边距设置 */ .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice { margin-left: 5px; margin-right: auto; } +/* 从右到左语言环境下多选选择器选项移除按钮左边距和右边距设置 */ .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { margin-left: 2px; margin-right: auto; } +/* 聚焦状态下多选选择器边框设置 */ .select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple { border: solid var(--body-quiet-color) 1px; outline: 0; } +/* 禁用状态下多选选择器背景和光标设置 */ .select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple { background-color: var(--darkened-bg); cursor: default; } +/* 禁用状态下多选选择器选项移除按钮显示设置 */ .select2-container--admin-autocomplete.select2-container--disabled .select2-selection__choice__remove { display: none; } +/* 打开状态下选择器上边框圆角设置 */ .select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--multiple { border-top-left-radius: 0; border-top-right-radius: 0; } +/* 打开状态下选择器下边框圆角设置 */ .select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--multiple { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } +/* 下拉搜索框背景设置 */ .select2-container--admin-autocomplete .select2-search--dropdown { background: var(--darkened-bg); } +/* 下拉搜索框字段背景、颜色、边框、圆角设置 */ .select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field { background: var(--body-bg); color: var(--body-fg); @@ -201,6 +239,7 @@ select.admin-autocomplete { border-radius: 4px; } +/* 内联搜索框字段背景、颜色、边框、轮廓和外观设置 */ .select2-container--admin-autocomplete .select2-search--inline .select2-search__field { background: transparent; color: var(--body-fg); @@ -210,6 +249,7 @@ select.admin-autocomplete { -webkit-appearance: textfield; } +/* 结果选项最大高度、溢出和颜色设置 */ .select2-container--admin-autocomplete .select2-results > .select2-results__options { max-height: 200px; overflow-y: auto; @@ -217,63 +257,76 @@ select.admin-autocomplete { background: var(--body-bg); } +/* 分组结果选项内边距设置 */ .select2-container--admin-autocomplete .select2-results__option[role=group] { padding: 0; } +/* 禁用结果选项颜色设置 */ .select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] { color: var(--body-quiet-color); } +/* 选中结果选项背景和颜色设置 */ .select2-container--admin-autocomplete .select2-results__option[aria-selected=true] { background-color: var(--selected-bg); color: var(--body-fg); } +/* 结果选项嵌套内边距设置 */ .select2-container--admin-autocomplete .select2-results__option .select2-results__option { padding-left: 1em; } +/* 结果选项嵌套分组内边距设置 */ .select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__group { padding-left: 0; } +/* 结果选项嵌套第二层内边距和左边距设置 */ .select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option { margin-left: -1em; padding-left: 2em; } +/* 结果选项嵌套第三层内边距和左边距设置 */ .select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -2em; padding-left: 3em; } +/* 结果选项嵌套第四层内边距和左边距设置 */ .select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -3em; padding-left: 4em; } +/* 结果选项嵌套第五层内边距和左边距设置 */ .select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -4em; padding-left: 5em; } +/* 结果选项嵌套第六层内边距和左边距设置 */ .select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -5em; padding-left: 6em; } +/* 高亮结果选项背景和颜色设置 */ .select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] { background-color: var(--primary); color: var(--primary-fg); } +/* 分组结果选项光标、显示、内边距设置 */ .select2-container--admin-autocomplete .select2-results__group { cursor: default; display: block; padding: 6px; } +/* 错误状态下选择器边框设置 */ .errors .select2-selection { border: 1px solid var(--error-fg); -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/base.css b/src/collectedstatic/admin/css/base.css index 3791043..a713178 100644 --- a/src/collectedstatic/admin/css/base.css +++ b/src/collectedstatic/admin/css/base.css @@ -1,7 +1,9 @@ /* + DJANGO管理界面样式 DJANGO Admin styles */ +/* 变量定义 */ /* VARIABLE DEFINITIONS */ html[data-theme="light"], :root { @@ -38,8 +40,8 @@ html[data-theme="light"], --message-warning-bg: #ffc; --message-error-bg: #ffefef; - --darkened-bg: #f8f8f8; /* A bit darker than --body-bg */ - --selected-bg: #e4e4e4; /* E.g. selected table cells */ + --darkened-bg: #f8f8f8; /* 比 --body-bg 稍暗一点 */ + --selected-bg: #e4e4e4; /* 例如选中的表格单元格 */ --selected-row: #ffc; --button-fg: #fff; @@ -102,6 +104,7 @@ body { background: var(--body-bg); } +/* 链接 */ /* LINKS */ a:link, a:visited { @@ -131,6 +134,7 @@ a.section:focus, a.section:hover { text-decoration: underline; } +/* 全局默认样式 */ /* GLOBAL DEFAULTS */ p, ol, ul, dl { @@ -260,6 +264,7 @@ hr { line-height: 1px; } +/* 文本样式和修饰符 */ /* TEXT STYLES & MODIFIERS */ .small { @@ -304,6 +309,7 @@ p img, h1 img, h2 img, h3 img, h4 img, td img { display: none !important; } +/* 表格 */ /* TABLES */ table { @@ -359,6 +365,7 @@ tr:nth-child(odd) + .row-form-errors .errorlist { background: var(--darkened-bg); } +/* 可排序表格 */ /* SORTABLE TABLES */ thead th { @@ -471,6 +478,7 @@ table thead th.sorted .sortoptions a.descending:hover { background-position: 0 -70px; } +/* 表单默认样式 */ /* FORM DEFAULTS */ input, textarea, select, .form-row p, form .button { @@ -490,8 +498,8 @@ textarea { } /* -Minifiers remove the default (text) "type" attribute from "input" HTML tags. -Add input:not([type]) to make the CSS stylesheet work the same. +最小化器会从"input" HTML标签中移除默认的(文本)"type"属性。 +添加input:not([type])使CSS样式表保持相同效果。 */ input:not([type]), input[type=text], input[type=password], input[type=email], input[type=url], input[type=number], input[type=tel], textarea, select, @@ -505,8 +513,8 @@ input[type=url], input[type=number], input[type=tel], textarea, select, } /* -Minifiers remove the default (text) "type" attribute from "input" HTML tags. -Add input:not([type]) to make the CSS stylesheet work the same. +最小化器会从"input" HTML标签中移除默认的(文本)"type"属性。 +添加input:not([type])使CSS样式表保持相同效果。 */ input:not([type]):focus, input[type=text]:focus, input[type=password]:focus, input[type=email]:focus, input[type=url]:focus, input[type=number]:focus, @@ -519,11 +527,12 @@ select { } select[multiple] { - /* Allow HTML size attribute to override the height in the rule above. */ + /* 允许HTML size属性覆盖上面的height规则 */ height: auto; min-height: 150px; } +/* 表单按钮 */ /* FORM BUTTONS */ .button, input[type=submit], input[type=button], .submit-row input, a.button { @@ -569,6 +578,7 @@ input[type=button][disabled].default { } +/* 模块 */ /* MODULES */ .module { @@ -615,6 +625,7 @@ input[type=button][disabled].default { border-collapse: collapse; } +/* 消息和错误 */ /* MESSAGES & ERRORS */ ul.messagelist { @@ -711,6 +722,7 @@ td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea { padding: 5px 0 0 12px; } +/* 面包屑导航 */ /* BREADCRUMBS */ div.breadcrumbs { @@ -729,6 +741,7 @@ div.breadcrumbs a:focus, div.breadcrumbs a:hover { color: var(--breadcrumbs-fg); } +/* 操作图标 */ /* ACTION ICONS */ .viewlink, .inlineviewlink { @@ -757,14 +770,15 @@ div.breadcrumbs a:focus, div.breadcrumbs a:hover { } a.deletelink:link, a.deletelink:visited { - color: #CC3434; /* XXX Probably unused? */ + color: #CC3434; /* XXX 可能未使用? */ } a.deletelink:focus, a.deletelink:hover { - color: #993333; /* XXX Probably unused? */ + color: #993333; /* XXX 可能未使用? */ text-decoration: none; } +/* 对象工具 */ /* OBJECT TOOLS */ .object-tools { @@ -821,6 +835,7 @@ a.deletelink:focus, a.deletelink:hover { background-image: url(../img/tooltag-add.svg); } +/* 对象历史 */ /* OBJECT HISTORY */ #change-history table { @@ -838,6 +853,7 @@ a.deletelink:focus, a.deletelink:hover { overflow: hidden; } +/* 页面结构 */ /* PAGE STRUCTURE */ #container { @@ -900,6 +916,7 @@ a.deletelink:focus, a.deletelink:hover { } } +/* 列类型 */ /* COLUMN TYPES */ .colMS { @@ -924,6 +941,7 @@ a.deletelink:focus, a.deletelink:hover { width: auto; } +/* 头部 */ /* HEADER */ #header { @@ -1019,6 +1037,7 @@ a.deletelink:focus, a.deletelink:hover { margin-bottom: 1px; } +/* 侧边栏 */ /* SIDEBAR */ #content-related { @@ -1095,6 +1114,7 @@ a.deletelink:focus, a.deletelink:hover { background: var(--close-button-hover-bg); } +/* 弹窗 */ /* POPUP */ .popup #content { padding: 20px; @@ -1108,6 +1128,7 @@ a.deletelink:focus, a.deletelink:hover { padding: 10px 20px; } +/* 分页器 */ /* PAGINATOR */ .paginator { @@ -1177,4 +1198,4 @@ a.deletelink:focus, a.deletelink:hover { border: 0; color: var(--body-fg); background-color: var(--body-bg); -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/changelists.css b/src/collectedstatic/admin/css/changelists.css index 005b776..61aac6d 100644 --- a/src/collectedstatic/admin/css/changelists.css +++ b/src/collectedstatic/admin/css/changelists.css @@ -1,3 +1,4 @@ +/* 变更列表 */ /* CHANGELISTS */ #changelist { @@ -50,6 +51,7 @@ overflow: hidden; } +/* 变更列表表格 */ /* CHANGELIST TABLES */ #changelist table thead th { @@ -71,6 +73,7 @@ color: var(--body-quiet-color); } +/* 工具栏 */ /* TOOLBAR */ #toolbar { @@ -129,6 +132,7 @@ word-break: break-word; } +/* 过滤器列 */ /* FILTER COLUMN */ #changelist-filter { @@ -227,6 +231,7 @@ border-bottom: 1px solid var(--hairline-color); } +/* 日期钻取 */ /* DATE DRILLDOWN */ .change-list .toplinks { @@ -250,6 +255,7 @@ color: var(--link-hover-color); } +/* 操作 */ /* ACTIONS */ .filtered .actions { @@ -261,6 +267,7 @@ vertical-align: baseline; } +/* 一旦所有浏览器都支持:has()伪类,可以移除tr.selected选择器和添加该类的JS代码 */ /* Once the :has() pseudo-class is supported by all browsers, the tr.selected selector and the JS adding the class can be removed. */ #changelist tbody tr.selected { @@ -340,4 +347,4 @@ #changelist .actions .button:focus, #changelist .actions .button:hover { border-color: var(--body-quiet-color); -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/dark_mode.css b/src/collectedstatic/admin/css/dark_mode.css index 65b58d0..546583e 100644 --- a/src/collectedstatic/admin/css/dark_mode.css +++ b/src/collectedstatic/admin/css/dark_mode.css @@ -1,41 +1,93 @@ +/* 深色模式媒体查询,当系统偏好设置为深色时应用 */ +/* Dark mode media query, applied when system preference is set to dark */ @media (prefers-color-scheme: dark) { :root { + /* 主色调 */ + /* Primary color */ --primary: #264b5d; + /* 主要前景色 */ + /* Primary foreground color */ --primary-fg: #f7f7f7; + /* 主体前景色 */ + /* Body foreground color */ --body-fg: #eeeeee; + /* 主体背景色 */ + /* Body background color */ --body-bg: #121212; + /* 主体安静色(较淡)*/ + /* Body quiet color (lighter) */ --body-quiet-color: #d0d0d0; + /* 主体中等颜色 */ + /* Body medium color */ --body-medium-color: #e0e0e0; + /* 主体响亮色(较亮)*/ + /* Body loud color (brighter) */ --body-loud-color: #ffffff; + /* 面包屑链接颜色 */ + /* Breadcrumbs link color */ --breadcrumbs-link-fg: #e0e0e0; + /* 面包屑背景色 */ + /* Breadcrumbs background color */ --breadcrumbs-bg: var(--primary); + /* 链接颜色 */ + /* Link color */ --link-fg: #81d4fa; + /* 链接悬停颜色 */ + /* Link hover color */ --link-hover-color: #4ac1f7; + /* 链接选中颜色 */ + /* Link selected color */ --link-selected-fg: #6f94c6; + /* 细线颜色 */ + /* Hairline color */ --hairline-color: #272727; + /* 边框颜色 */ + /* Border color */ --border-color: #353535; + /* 错误颜色 */ + /* Error color */ --error-fg: #e35f5f; + /* 成功消息背景色 */ + /* Success message background color */ --message-success-bg: #006b1b; + /* 警告消息背景色 */ + /* Warning message background color */ --message-warning-bg: #583305; + /* 错误消息背景色 */ + /* Error message background color */ --message-error-bg: #570808; + /* 深色背景 */ + /* Darkened background */ --darkened-bg: #212121; + /* 选中背景色 */ + /* Selected background color */ --selected-bg: #1b1b1b; + /* 选中行颜色 */ + /* Selected row color */ --selected-row: #00363a; + /* 关闭按钮背景色 */ + /* Close button background color */ --close-button-bg: #333333; + /* 关闭按钮悬停背景色 */ + /* Close button hover background color */ --close-button-hover-bg: #666666; + /* 颜色方案设置为深色 */ + /* Color scheme set to dark */ color-scheme: dark; } } +/* 当HTML元素的data-theme属性为"dark"时应用的样式 */ +/* Styles applied when HTML element's data-theme attribute is "dark" */ html[data-theme="dark"] { --primary: #264b5d; --primary-fg: #f7f7f7; @@ -71,25 +123,51 @@ html[data-theme="dark"] { color-scheme: dark; } -/* THEME SWITCH */ +/* 主题切换按钮样式 */ +/* Theme switch button styles */ .theme-toggle { + /* 设置光标为指针 */ + /* Set cursor to pointer */ cursor: pointer; + /* 移除边框 */ + /* Remove border */ border: none; + /* 设置内边距为0 */ + /* Set padding to 0 */ padding: 0; + /* 设置背景为透明 */ + /* Set background to transparent */ background: transparent; + /* 设置垂直对齐方式 */ + /* Set vertical alignment */ vertical-align: middle; + /* 设置左边距 */ + /* Set left margin */ margin-inline-start: 5px; + /* 设置上边距 */ + /* Set top margin */ margin-top: -1px; } +/* 主题切换按钮中的SVG图标样式 */ +/* SVG icon styles in theme toggle button */ .theme-toggle svg { + /* 设置垂直对齐方式 */ + /* Set vertical alignment */ vertical-align: middle; + /* 设置高度 */ + /* Set height */ height: 1.5rem; + /* 设置宽度 */ + /* Set width */ width: 1.5rem; + /* 默认不显示 */ + /* Hidden by default */ display: none; } /* +完全隐藏屏幕阅读器文本,只显示匹配当前主题的文本。 Fully hide screen reader text so we only show the one matching the current theme. */ @@ -97,19 +175,26 @@ theme. display: none; } +/* 当data-theme属性为"auto"时显示自动主题标签 */ +/* Show auto theme label when data-theme attribute is "auto" */ html[data-theme="auto"] .theme-toggle .theme-label-when-auto { display: block; } +/* 当data-theme属性为"dark"时显示深色主题标签 */ +/* Show dark theme label when data-theme attribute is "dark" */ html[data-theme="dark"] .theme-toggle .theme-label-when-dark { display: block; } +/* 当data-theme属性为"light"时显示浅色主题标签 */ +/* Show light theme label when data-theme attribute is "light" */ html[data-theme="light"] .theme-toggle .theme-label-when-light { display: block; } -/* ICONS */ +/* 图标样式 */ +/* Icon styles */ .theme-toggle svg.theme-icon-when-auto, .theme-toggle svg.theme-icon-when-dark, .theme-toggle svg.theme-icon-when-light { @@ -117,14 +202,20 @@ html[data-theme="light"] .theme-toggle .theme-label-when-light { color: var(--header-bg); } +/* 当data-theme属性为"auto"时显示自动主题图标 */ +/* Show auto theme icon when data-theme attribute is "auto" */ html[data-theme="auto"] .theme-toggle svg.theme-icon-when-auto { display: block; } +/* 当data-theme属性为"dark"时显示深色主题图标 */ +/* Show dark theme icon when data-theme attribute is "dark" */ html[data-theme="dark"] .theme-toggle svg.theme-icon-when-dark { display: block; } +/* 当data-theme属性为"light"时显示浅色主题图标 */ +/* Show light theme icon when data-theme attribute is "light" */ html[data-theme="light"] .theme-toggle svg.theme-icon-when-light { display: block; -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/dashboard.css b/src/collectedstatic/admin/css/dashboard.css index 242b81a..90a1f8b 100644 --- a/src/collectedstatic/admin/css/dashboard.css +++ b/src/collectedstatic/admin/css/dashboard.css @@ -1,3 +1,4 @@ +/* 仪表板 */ /* DASHBOARD */ .dashboard td, .dashboard th { word-break: break-word; @@ -16,6 +17,7 @@ padding-right: .6em; } +/* 最近操作模块 */ /* RECENT ACTIONS MODULE */ .module ul.actionlist { @@ -26,4 +28,4 @@ ul.actionlist li { list-style-type: none; overflow: hidden; text-overflow: ellipsis; -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/forms.css b/src/collectedstatic/admin/css/forms.css index c6ce788..23bf5db 100644 --- a/src/collectedstatic/admin/css/forms.css +++ b/src/collectedstatic/admin/css/forms.css @@ -1,5 +1,7 @@ +/* 导入小部件样式 */ @import url('widgets.css'); +/* 表单行 */ /* FORM ROWS */ .form-row { @@ -34,6 +36,7 @@ form .form-row p { padding-bottom: 10px; } +/* 表单标签 */ /* FORM LABELS */ label { @@ -46,6 +49,7 @@ label { font-weight: bold; } +/* 单选按钮 */ /* RADIO BUTTONS */ form div.radiolist div { @@ -75,6 +79,7 @@ form ul.inline li { padding-right: 7px; } +/* 字段集 */ /* FIELDSETS */ fieldset .fieldset-heading, @@ -89,6 +94,7 @@ fieldset .inline-heading, color: var(--header-link-color); } +/* 对齐的字段集 */ /* ALIGNED FIELDSETS */ .aligned label { @@ -199,6 +205,7 @@ fieldset .fieldBox { margin-right: 20px; } +/* 宽字段集 */ /* WIDE FIELDSETS */ .wide label { @@ -220,6 +227,7 @@ form div.help ul { width: 450px; } +/* 可折叠字段集 */ /* COLLAPSIBLE FIELDSETS */ .collapse summary .fieldset-heading, @@ -232,12 +240,14 @@ form div.help ul { padding: 0; } +/* 等宽字体文本区域 */ /* MONOSPACE TEXTAREAS */ fieldset.monospace textarea { font-family: var(--font-family-monospace); } +/* 提交行 */ /* SUBMIT ROW */ .submit-row { @@ -307,6 +317,7 @@ body.popup .submit-row { text-decoration: none; } +/* 自定义表单字段 */ /* CUSTOM FORM FIELDS */ .vSelectMultipleField { @@ -362,6 +373,7 @@ body.popup .submit-row { width: 20em; } +/* 行内组 */ /* INLINES */ .inline-group { @@ -471,6 +483,7 @@ body.popup .submit-row { display: none; } +/* 相关字段添加一个/查找 */ /* RELATED FIELD ADD ONE / LOOKUP */ .related-lookup { @@ -495,4 +508,4 @@ form .related-widget-wrapper ul { .clearable-file-input input { margin-top: 0; -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/login.css b/src/collectedstatic/admin/css/login.css index 805a34b..84bb072 100644 --- a/src/collectedstatic/admin/css/login.css +++ b/src/collectedstatic/admin/css/login.css @@ -1,61 +1,89 @@ +/* 登录表单样式 */ /* LOGIN FORM */ .login { + /* 设置背景色 */ background: var(--darkened-bg); + /* 设置高度为自动 */ height: auto; } .login #header { + /* 设置头部高度为自动 */ height: auto; + /* 设置内边距 */ padding: 15px 16px; + /* 设置内容居中对齐 */ justify-content: center; } .login #header h1 { + /* 设置标题字体大小 */ font-size: 1.125rem; + /* 设置外边距 */ margin: 0; } .login #header h1 a { + /* 设置链接颜色 */ color: var(--header-link-color); } .login #content { + /* 设置内容区内边距 */ padding: 20px; } .login #container { + /* 设置容器背景色 */ background: var(--body-bg); + /* 设置边框 */ border: 1px solid var(--hairline-color); + /* 设置圆角 */ border-radius: 4px; + /* 设置溢出隐藏 */ overflow: hidden; + /* 设置宽度 */ width: 28em; + /* 设置最小宽度 */ min-width: 300px; + /* 设置外边距居中 */ margin: 100px auto; + /* 设置高度为自动 */ height: auto; } .login .form-row { + /* 设置表单行内边距 */ padding: 4px 0; } .login .form-row label { + /* 设置标签为块级元素 */ display: block; + /* 设置行高 */ line-height: 2em; } .login .form-row #id_username, .login .form-row #id_password { + /* 设置内边距 */ padding: 8px; + /* 设置宽度为100% */ width: 100%; + /* 设置盒模型为border-box */ box-sizing: border-box; } .login .submit-row { + /* 设置提交行内边距 */ padding: 1em 0 0 0; + /* 设置外边距 */ margin: 0; + /* 设置文本居中对齐 */ text-align: center; } .login .password-reset-link { + /* 设置密码重置链接文本居中对齐 */ text-align: center; -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/nav_sidebar.css b/src/collectedstatic/admin/css/nav_sidebar.css index 7eb0de9..9ff6dc7 100644 --- a/src/collectedstatic/admin/css/nav_sidebar.css +++ b/src/collectedstatic/admin/css/nav_sidebar.css @@ -1,9 +1,13 @@ +/* 粘性定位 - 使侧边栏在滚动时保持在顶部 */ +/* sticky */ .sticky { position: sticky; top: 0; max-height: 100vh; } +/* 切换导航侧边栏按钮 */ +/* 切换导航侧边栏按钮 */ .toggle-nav-sidebar { z-index: 20; left: 0; @@ -21,16 +25,19 @@ padding: 0; } +/* 从右到左语言环境下的切换按钮边框调整 */ [dir="rtl"] .toggle-nav-sidebar { border-left: 1px solid var(--hairline-color); border-right: 0; } +/* 切换按钮的悬停和焦点状态 */ .toggle-nav-sidebar:hover, .toggle-nav-sidebar:focus { background-color: var(--darkened-bg); } +/* 导航侧边栏 */ #nav-sidebar { z-index: 15; flex: 0 0 275px; @@ -42,6 +49,7 @@ overflow: auto; } +/* 从右到左语言环境下的导航侧边栏调整 */ [dir="rtl"] #nav-sidebar { border-left: 1px solid var(--hairline-color); border-right: 0; @@ -51,82 +59,99 @@ margin-right: -276px; } +/* 切换导航侧边栏按钮的:before伪元素内容 */ .toggle-nav-sidebar::before { content: '\00BB'; } +/* 主内容区域移动时切换按钮的:before伪元素内容 */ .main.shifted .toggle-nav-sidebar::before { content: '\00AB'; } +/* 主内容区域的导航侧边栏可见性 */ .main > #nav-sidebar { visibility: hidden; } +/* 主内容区域移动时导航侧边栏的可见性 */ .main.shifted > #nav-sidebar { margin-left: 0; visibility: visible; } +/* 从右到左语言环境下主内容区域移动时导航侧边栏的右边距 */ [dir="rtl"] .main.shifted > #nav-sidebar { margin-right: 0; } +/* 导航侧边栏模块标题的宽度和换行处理 */ #nav-sidebar .module th { width: 100%; overflow-wrap: anywhere; } +/* 导航侧边栏模块标题和说明文字的内边距 */ #nav-sidebar .module th, #nav-sidebar .module caption { padding-left: 16px; } +/* 导航侧边栏模块数据单元格的空白处理 */ #nav-sidebar .module td { white-space: nowrap; } +/* 从右到左语言环境下导航侧边栏模块标题和说明文字的内边距调整 */ [dir="rtl"] #nav-sidebar .module th, [dir="rtl"] #nav-sidebar .module caption { padding-left: 8px; padding-right: 16px; } +/* 当前应用的节链接样式 */ #nav-sidebar .current-app .section:link, #nav-sidebar .current-app .section:visited { color: var(--header-color); font-weight: bold; } +/* 当前模型的背景色 */ #nav-sidebar .current-model { background: var(--selected-row); } +/* 强制颜色模式下当前模型的背景色 */ @media (forced-colors: active) { #nav-sidebar .current-model { background-color: SelectedItem; } } +/* 主内容区域导航侧边栏和内容的最大宽度 */ .main > #nav-sidebar + .content { max-width: calc(100% - 23px); } +/* 主内容区域移动时导航侧边栏和内容的最大宽度 */ .main.shifted > #nav-sidebar + .content { max-width: calc(100% - 299px); } +/* 移动设备样式 - 隐藏导航侧边栏和切换按钮 */ @media (max-width: 767px) { #nav-sidebar, #toggle-nav-sidebar { display: none; } + /* 移动设备上主内容区域的最大宽度 */ .main > #nav-sidebar + .content, .main.shifted > #nav-sidebar + .content { max-width: 100%; } } +/* 导航过滤器输入框样式 */ #nav-filter { width: 100%; box-sizing: border-box; @@ -137,14 +162,17 @@ color: var(--body-fg); } +/* 导航过滤器输入框的焦点状态 */ #nav-filter:focus { border-color: var(--body-quiet-color); } +/* 导航过滤器无结果时的背景色 */ #nav-filter.no-results { background: var(--message-error-bg); } +/* 导航侧边栏表格宽度 */ #nav-sidebar table { width: 100%; -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/responsive.css b/src/collectedstatic/admin/css/responsive.css index f0fcade..6b606ab 100644 --- a/src/collectedstatic/admin/css/responsive.css +++ b/src/collectedstatic/admin/css/responsive.css @@ -1,3 +1,4 @@ +/* 平板设备 */ /* Tablets */ input[type="submit"], button { @@ -6,6 +7,7 @@ input[type="submit"], button { } @media (max-width: 1024px) { + /* 基础样式 */ /* Basic */ html { @@ -21,6 +23,7 @@ input[type="submit"], button { font-size: 0.75rem; } + /* 布局 */ /* Layout */ #container { @@ -35,6 +38,7 @@ input[type="submit"], button { padding: 10px 30px; } + /* 头部 */ /* Header */ #header { @@ -60,6 +64,7 @@ input[type="submit"], button { line-height: 1.4; } + /* 仪表板 */ /* Dashboard */ .dashboard #content { @@ -90,6 +95,7 @@ input[type="submit"], button { font-size: 0.8125rem; } + /* 变更列表 */ /* Changelist */ #toolbar { @@ -168,6 +174,7 @@ input[type="submit"], button { border-top: none; } + /* 表单 */ /* Forms */ label { @@ -175,8 +182,8 @@ input[type="submit"], button { } /* - Minifiers remove the default (text) "type" attribute from "input" HTML - tags. Add input:not([type]) to make the CSS stylesheet work the same. + 最小化器会从"input" HTML标签中移除默认的(文本)"type"属性。 + 添加input:not([type])使CSS样式表保持相同效果。 */ .form-row input:not([type]), .form-row input[type=text], @@ -242,6 +249,7 @@ input[type="submit"], button { padding: 7px; } + /* 选择器 */ /* Selector */ .selector { @@ -334,6 +342,7 @@ input[type="submit"], button { overflow: auto; } + /* 消息 */ /* Messages */ ul.messagelist li { @@ -349,6 +358,7 @@ input[type="submit"], button { background-position: 30px 14px; } + /* 登录 */ /* Login */ .login #header { @@ -371,6 +381,7 @@ input[type="submit"], button { margin-top: 10px; } + /* 文档 */ /* Docs */ .module table.xfull { @@ -382,9 +393,11 @@ input[type="submit"], button { } } +/* 移动设备 */ /* Mobile */ @media (max-width: 767px) { + /* 布局 */ /* Layout */ #header, #content { @@ -395,6 +408,7 @@ input[type="submit"], button { padding: 10px 15px; } + /* 仪表板 */ /* Dashboard */ .colMS, .colSM { @@ -415,6 +429,7 @@ input[type="submit"], button { font-size: 1rem; } + /* 变更列表 */ /* Changelist */ #changelist { @@ -465,6 +480,7 @@ input[type="submit"], button { margin-left: 15px; } + /* 表单 */ /* Forms */ .form-row { @@ -575,6 +591,7 @@ input[type="submit"], button { margin-top: 5px; } + /* 相关小部件 */ /* Related widget */ .related-widget-wrapper { @@ -600,6 +617,7 @@ input[type="submit"], button { align-self: center; } + /* 选择器 */ /* Selector */ .selector { @@ -643,6 +661,7 @@ input[type="submit"], button { background-position: 0 -72px; } + /* 行内组 */ /* Inlines */ .inline-group[data-inline-type="stacked"] .inline-related { @@ -714,6 +733,7 @@ input[type="submit"], button { background-position: 8px 9px; } + /* 提交行 */ /* Submit row */ .submit-row { @@ -736,6 +756,7 @@ input[type="submit"], button { margin: 0; } + /* 消息 */ /* Messages */ ul.messagelist li { @@ -751,12 +772,14 @@ input[type="submit"], button { background-position: 15px 14px; } + /* 分页器 */ /* Paginator */ .paginator .this-page, .paginator a:link, .paginator a:visited { padding: 4px 10px; } + /* 登录 */ /* Login */ body.login { @@ -810,6 +833,7 @@ input[type="submit"], button { font-size: 0.8125rem; } + /* 日历和时钟 */ /* Calendar and clock */ .calendarbox, .clockbox { @@ -884,6 +908,7 @@ input[type="submit"], button { top: 10px; } + /* 历史记录 */ /* History */ table#change-history tbody th, table#change-history tbody td { @@ -895,10 +920,11 @@ input[type="submit"], button { width: auto; } + /* 文档 */ /* Docs */ table.model tbody th, table.model tbody td { font-size: 0.8125rem; word-break: break-word; } -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/responsive_rtl.css b/src/collectedstatic/admin/css/responsive_rtl.css index 5e8f5c5..eff7623 100644 --- a/src/collectedstatic/admin/css/responsive_rtl.css +++ b/src/collectedstatic/admin/css/responsive_rtl.css @@ -1,24 +1,30 @@ +/* 平板设备样式 */ /* TABLETS */ @media (max-width: 1024px) { + /* 从右到左的语言布局调整 */ [dir="rtl"] .colMS { margin-right: 0; } + /* 用户工具栏文本对齐调整 */ [dir="rtl"] #user-tools { text-align: right; } + /* 变更列表操作标签内边距调整 */ [dir="rtl"] #changelist .actions label { padding-left: 10px; padding-right: 0; } + /* 变更列表操作选择框边距调整 */ [dir="rtl"] #changelist .actions select { margin-left: 0; margin-right: 15px; } + /* 过滤器相关元素的边距调整 */ [dir="rtl"] .change-list .filtered .results, [dir="rtl"] .change-list .filtered .paginator, [dir="rtl"] .filtered #toolbar, @@ -28,62 +34,76 @@ margin-left: 0; } + /* 行内组添加行链接的内边距和背景位置调整 */ [dir="rtl"] .inline-group div.add-row a, [dir="rtl"] .inline-group .tabular tr.add-row td a { padding: 8px 26px 8px 10px; background-position: calc(100% - 8px) 9px; } + /* 对象工具列表项浮动方向调整 */ [dir="rtl"] .object-tools li { float: right; } + /* 对象工具相邻列表项的边距调整 */ [dir="rtl"] .object-tools li + li { margin-left: 0; margin-right: 15px; } + /* 仪表板模块表格链接内边距调整 */ [dir="rtl"] .dashboard .module table td a { padding-left: 0; padding-right: 16px; } } +/* 移动设备样式 */ /* MOBILE */ @media (max-width: 767px) { + /* 相关查找和日期时间快捷方式的边距调整 */ [dir="rtl"] .aligned .related-lookup, [dir="rtl"] .aligned .datetimeshortcuts { margin-left: 0; margin-right: 15px; } + /* 列表的右边距调整 */ [dir="rtl"] .aligned ul, [dir="rtl"] form .aligned ul.errorlist { margin-right: 0; } + /* 变更列表过滤器的边距调整 */ [dir="rtl"] #changelist-filter { margin-left: 0; margin-right: 0; } + + /* 复选框标签的内边距调整 */ [dir="rtl"] .aligned .vCheckboxLabel { padding: 1px 5px 0 0; } + /* 选择器移除按钮的背景位置调整 */ [dir="rtl"] .selector-remove { background-position: 0 0; } + /* 选择器移除按钮的焦点和悬停状态背景位置调整 */ [dir="rtl"] :enabled.selector-remove:focus, :enabled.selector-remove:hover { background-position: 0 -24px; } + /* 选择器添加按钮的背景位置调整 */ [dir="rtl"] .selector-add { background-position: 0 -48px; } + /* 选择器添加按钮的焦点和悬停状态背景位置调整 */ [dir="rtl"] :enabled.selector-add:focus, :enabled.selector-add:hover { background-position: 0 -72px; } -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/rtl.css b/src/collectedstatic/admin/css/rtl.css index a2556d0..0582d7c 100644 --- a/src/collectedstatic/admin/css/rtl.css +++ b/src/collectedstatic/admin/css/rtl.css @@ -1,91 +1,113 @@ +/* 全局样式 - 适用于从右到左的语言 */ /* GLOBAL */ +/* 表格标题文本对齐 */ th { text-align: right; } +/* 模块标题和说明文字对齐 */ .module h2, .module caption { text-align: right; } +/* 模块列表的左右边距调整 */ .module ul, .module ol { margin-left: 0; margin-right: 1.5em; } +/* 查看、添加、变更、隐藏链接的内边距和背景位置调整 */ .viewlink, .addlink, .changelink, .hidelink { padding-left: 0; padding-right: 16px; background-position: 100% 1px; } +/* 删除链接的内边距和背景位置调整 */ .deletelink { padding-left: 0; padding-right: 16px; background-position: 100% 1px; } +/* 对象工具栏浮动方向 */ .object-tools { float: left; } +/* 表格首列的边框调整 */ thead th:first-child, tfoot td:first-child { border-left: none; } +/* 布局相关样式 */ /* LAYOUT */ +/* 用户工具栏位置和文本对齐调整 */ #user-tools { right: auto; left: 0; text-align: left; } +/* 面包屑导航文本对齐 */ div.breadcrumbs { text-align: right; } +/* 主内容区域浮动方向 */ #content-main { float: right; } +/* 相关内容区域浮动方向和边距调整 */ #content-related { float: left; margin-left: -300px; margin-right: auto; } +/* 主列和侧边栏布局调整 */ .colMS { margin-left: 300px; margin-right: 0; } +/* 可排序表格样式 */ /* SORTABLE TABLES */ +/* 排序选项浮动方向 */ table thead th.sorted .sortoptions { float: left; } +/* 已排序列文本内边距调整 */ thead th.sorted .text { padding-right: 0; padding-left: 42px; } +/* 仪表板样式 */ /* dashboard styles */ +/* 仪表板模块表格链接内边距调整 */ .dashboard .module table td a { padding-left: .6em; padding-right: 16px; } +/* 变更列表样式 */ /* changelists styles */ +/* 过滤变更列表的表格边框调整 */ .change-list .filtered table { border-left: none; border-right: 0px none; } +/* 变更列表过滤器边框和边距调整 */ #changelist-filter { border-left: none; border-right: none; @@ -93,6 +115,7 @@ thead th.sorted .text { margin-right: 30px; } +/* 已选过滤条件的边框、内边距和边距调整 */ #changelist-filter li.selected { border-left: none; padding-left: 10px; @@ -102,40 +125,49 @@ thead th.sorted .text { margin-right: -15px; } +/* 变更列表表格首列的边框调整 */ #changelist table tbody td:first-child, #changelist table tbody th:first-child { border-right: none; border-left: none; } +/* 分页器末页链接的边距调整 */ .paginator .end { margin-left: 6px; margin-right: 0; } +/* 分页器输入框的边距调整 */ .paginator input { margin-left: 0; margin-right: auto; } +/* 表单样式 */ /* FORMS */ +/* 对齐标签的内边距调整 */ .aligned label { padding: 0 0 3px 1em; } +/* 删除链接的边距调整 */ .submit-row a.deletelink { margin-left: 0; margin-right: auto; } +/* 日期和时间字段的边距调整 */ .vDateField, .vTimeField { margin-left: 2px; } +/* 对齐表单行输入框的边距调整 */ .aligned .form-row input { margin-left: 5px; } +/* 对齐列表的边距和内边距调整 */ form .aligned ul { margin-right: 163px; padding-right: 10px; @@ -143,12 +175,14 @@ form .aligned ul { padding-left: 0; } +/* 行内列表项的浮动方向和内边距调整 */ form ul.inline li { float: right; padding-right: 0; padding-left: 7px; } +/* 表单帮助文本的边距和内边距调整 */ form .aligned p.help, form .aligned div.help { margin-left: 0; @@ -156,6 +190,7 @@ form .aligned div.help { padding-right: 10px; } +/* 帮助文本列表、复选框行和时区警告的边距调整 */ form div.help ul, form .aligned .checkbox-row + .help, form .aligned p.date div.help.timezonewarning, @@ -165,6 +200,7 @@ form .aligned p.time div.help.timezonewarning { padding-right: 0; } +/* 宽表单帮助文本、错误列表和帮助文本的内边距调整 */ form .wide p.help, form .wide ul.errorlist, form .wide div.help { @@ -172,27 +208,33 @@ form .wide div.help { padding-right: 50px; } +/* 提交行文本对齐 */ .submit-row { text-align: right; } +/* 字段框的边距调整 */ fieldset .fieldBox { margin-left: 20px; margin-right: 0; } +/* 错误列表项的背景位置和内边距调整 */ .errorlist li { background-position: 100% 12px; padding: 0; } +/* 错误提示的背景位置和内边距调整 */ .errornote { background-position: 100% 12px; padding: 10px 12px; } +/* 小部件样式 */ /* WIDGETS */ +/* 日历导航上一个按钮的位置和背景调整 */ .calendarnav-previous { top: 0; left: auto; @@ -200,6 +242,7 @@ fieldset .fieldBox { background: url(../img/calendar-icons.svg) 0 -15px no-repeat; } +/* 日历导航下一个按钮的位置和背景调整 */ .calendarnav-next { top: 0; right: auto; @@ -207,70 +250,87 @@ fieldset .fieldBox { background: url(../img/calendar-icons.svg) 0 0 no-repeat; } +/* 日历标题和日历框标题文本对齐 */ .calendar caption, .calendarbox h2 { text-align: center; } +/* 选择器浮动方向 */ .selector { float: right; } +/* 选择器过滤器文本对齐 */ .selector .selector-filter { text-align: right; } +/* 选择器添加按钮的背景和背景大小调整 */ .selector-add { background: url(../img/selector-icons.svg) 0 -96px no-repeat; background-size: 24px auto; } +/* 选择器添加按钮的焦点和悬停状态背景位置调整 */ :enabled.selector-add:focus, :enabled.selector-add:hover { background-position: 0 -120px; } +/* 选择器移除按钮的背景和背景大小调整 */ .selector-remove { background: url(../img/selector-icons.svg) 0 -144px no-repeat; background-size: 24px auto; } +/* 选择器移除按钮的焦点和悬停状态背景位置调整 */ :enabled.selector-remove:focus, :enabled.selector-remove:hover { background-position: 0 -168px; } +/* 全选按钮的背景调整 */ .selector-chooseall { background: url(../img/selector-icons.svg) right -128px no-repeat; } +/* 全选按钮的焦点和悬停状态背景位置调整 */ :enabled.selector-chooseall:focus, :enabled.selector-chooseall:hover { background-position: 100% -144px; } +/* 全清按钮的背景调整 */ .selector-clearall { background: url(../img/selector-icons.svg) 0 -160px no-repeat; } +/* 全清按钮的焦点和悬停状态背景位置调整 */ :enabled.selector-clearall:focus, :enabled.selector-clearall:hover { background-position: 0 -176px; } +/* 行内删除链接浮动方向 */ .inline-deletelink { float: left; } +/* 日期时间表单行的溢出处理 */ form .form-row p.datetime { overflow: hidden; } +/* 相关小部件包装器的浮动方向 */ .related-widget-wrapper { float: right; } +/* 其他样式 */ /* MISC */ +/* 行内相关标题和行内组标题文本对齐 */ .inline-related h2, .inline-group h2 { text-align: right } +/* 行内相关标题删除链接的内边距、位置和浮动方向调整 */ .inline-related h3 span.delete { padding-right: 20px; padding-left: inherit; @@ -279,15 +339,18 @@ form .form-row p.datetime { float:left; } +/* 行内相关标题删除链接标签的边距调整 */ .inline-related h3 span.delete label { margin-left: inherit; margin-right: 2px; } +/* 行内组表格原始列段落的右边距调整 */ .inline-group .tabular td.original p { right: 0; } +/* 选择器选择器的边距调整 */ .selector .selector-chooser { margin: 0; -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/unusable_password_field.css b/src/collectedstatic/admin/css/unusable_password_field.css index d46eb03..1bfa9ea 100644 --- a/src/collectedstatic/admin/css/unusable_password_field.css +++ b/src/collectedstatic/admin/css/unusable_password_field.css @@ -1,14 +1,17 @@ +/* 当用户选择可用密码时隐藏警告字段 */ /* Hide warnings fields if usable password is selected */ form:has(#id_usable_password input[value="true"]:checked) .messagelist { display: none; } +/* 当用户选择不可用密码时隐藏密码字段 */ /* Hide password fields if unusable password is selected */ form:has(#id_usable_password input[value="false"]:checked) .field-password1, form:has(#id_usable_password input[value="false"]:checked) .field-password2 { display: none; } +/* 选择适当的提交按钮 */ /* Select appropriate submit button */ form:has(#id_usable_password input[value="true"]:checked) input[type="submit"].unset-password { display: none; @@ -16,4 +19,4 @@ form:has(#id_usable_password input[value="true"]:checked) input[type="submit"].u form:has(#id_usable_password input[value="false"]:checked) input[type="submit"].set-password { display: none; -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/vendor/select2/select2.min.css b/src/collectedstatic/admin/css/vendor/select2/select2.min.css index 7c18ad5..29d27bd 100644 --- a/src/collectedstatic/admin/css/vendor/select2/select2.min.css +++ b/src/collectedstatic/admin/css/vendor/select2/select2.min.css @@ -1 +1,3 @@ -.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} +/* 这是Select2插件的压缩CSS样式文件 */ +/* This is the minified CSS file for the Select2 plugin */ +.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} \ No newline at end of file diff --git a/src/collectedstatic/admin/css/widgets.css b/src/collectedstatic/admin/css/widgets.css index 538af2e..92fa79f 100644 --- a/src/collectedstatic/admin/css/widgets.css +++ b/src/collectedstatic/admin/css/widgets.css @@ -1,3 +1,4 @@ +/* 选择器(过滤器界面)*/ /* SELECTOR (FILTER INTERFACE) */ .selector { @@ -207,6 +208,7 @@ background-position: 0 -144px; } +/* 堆叠选择器 */ /* STACKED SELECTORS */ .stacked { @@ -303,6 +305,7 @@ width: 1.125rem; } +/* 日期和时间 */ /* DATE AND TIME */ p.datetime { @@ -381,6 +384,7 @@ p.url { font-weight: normal; } +/* 文件上传 */ /* FILE UPLOADS */ p.file-upload { @@ -407,6 +411,7 @@ span.clearable-file-input label { float: none; } +/* 日历和时钟 */ /* CALENDARS & CLOCKS */ .calendarbox, .clockbox { @@ -571,6 +576,7 @@ ul.timelist, .timelist li { padding: 2px; } +/* 行内编辑 */ /* EDIT INLINE */ .inline-deletelink { @@ -587,6 +593,7 @@ ul.timelist, .timelist li { cursor: pointer; } +/* 相关小部件包装器 */ /* RELATED WIDGET WRAPPER */ .related-widget-wrapper { display: flex; @@ -606,8 +613,9 @@ ul.timelist, .timelist li { filter: grayscale(0); } +/* GIS地图 */ /* GIS MAPS */ .dj_map { width: 600px; height: 400px; -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/js/SelectBox.js b/src/collectedstatic/admin/js/SelectBox.js index 3db4ec7..86e300d 100644 --- a/src/collectedstatic/admin/js/SelectBox.js +++ b/src/collectedstatic/admin/js/SelectBox.js @@ -1,66 +1,111 @@ 'use strict'; { const SelectBox = { - cache: {}, + cache: {}, // 选择框缓存,用于存储选项数据 + + /** + * 初始化选择框缓存 + * @param {string} id - 选择框元素的ID + */ init: function(id) { const box = document.getElementById(id); SelectBox.cache[id] = []; const cache = SelectBox.cache[id]; + // 将选择框中的所有选项添加到缓存中 for (const node of box.options) { cache.push({value: node.value, text: node.text, displayed: 1}); } }, + + /** + * 从缓存重新显示HTML选择框 + * @param {string} id - 选择框元素的ID + */ redisplay: function(id) { - // Repopulate HTML select box from cache + // 从缓存重新填充HTML选择框 const box = document.getElementById(id); const scroll_value_from_top = box.scrollTop; box.innerHTML = ''; + // 只显示标记为displayed的选项 for (const node of SelectBox.cache[id]) { if (node.displayed) { const new_option = new Option(node.text, node.value, false, false); - // Shows a tooltip when hovering over the option + // 鼠标悬停时显示提示工具 new_option.title = node.text; box.appendChild(new_option); } } box.scrollTop = scroll_value_from_top; }, + + /** + * 根据文本过滤选择框中的选项 + * @param {string} id - 选择框元素的ID + * @param {string} text - 过滤文本 + */ filter: function(id, text) { - // Redisplay the HTML select box, displaying only the choices containing ALL - // the words in text. (It's an AND search.) + // 重新显示HTML选择框,仅显示包含文本中所有单词的选项(AND搜索) const tokens = text.toLowerCase().split(/\s+/); for (const node of SelectBox.cache[id]) { node.displayed = 1; const node_text = node.text.toLowerCase(); + // 检查每个词是否都包含在选项文本中 for (const token of tokens) { if (!node_text.includes(token)) { node.displayed = 0; - break; // Once the first token isn't found we're done + break; // 一旦第一个词未找到就结束 } } } SelectBox.redisplay(id); }, + + /** + * 获取隐藏节点数量 + * @param {string} id - 选择框元素的ID + * @returns {number} 隐藏节点的数量 + */ get_hidden_node_count(id) { const cache = SelectBox.cache[id] || []; return cache.filter(node => node.displayed === 0).length; }, + + /** + * 从缓存中删除指定值的选项 + * @param {string} id - 选择框元素的ID + * @param {string} value - 要删除的选项值 + */ delete_from_cache: function(id, value) { let delete_index = null; const cache = SelectBox.cache[id]; + // 查找要删除的选项索引 for (const [i, node] of cache.entries()) { if (node.value === value) { delete_index = i; break; } } + // 从缓存中删除选项 cache.splice(delete_index, 1); }, + + /** + * 向缓存中添加选项 + * @param {string} id - 选择框元素的ID + * @param {HTMLOptionElement} option - 要添加的选项元素 + */ add_to_cache: function(id, option) { SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); }, + + /** + * 检查缓存中是否包含指定值的选项 + * @param {string} id - 选择框元素的ID + * @param {string} value - 要检查的选项值 + * @returns {boolean} 如果包含则返回true,否则返回false + */ cache_contains: function(id, value) { - // Check if an item is contained in the cache + // 检查项目是否包含在缓存中 for (const node of SelectBox.cache[id]) { if (node.value === value) { return true; @@ -68,30 +113,53 @@ } return false; }, + + /** + * 将选中的选项从一个选择框移动到另一个选择框 + * @param {string} from - 源选择框ID + * @param {string} to - 目标选择框ID + */ move: function(from, to) { const from_box = document.getElementById(from); + // 遍历源选择框中的所有选项 for (const option of from_box.options) { const option_value = option.value; + // 如果选项被选中且在缓存中存在,则移动它 if (option.selected && SelectBox.cache_contains(from, option_value)) { SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1}); SelectBox.delete_from_cache(from, option_value); } } + // 重新显示两个选择框 SelectBox.redisplay(from); SelectBox.redisplay(to); }, + + /** + * 将所有选项从一个选择框移动到另一个选择框 + * @param {string} from - 源选择框ID + * @param {string} to - 目标选择框ID + */ move_all: function(from, to) { const from_box = document.getElementById(from); + // 遍历源选择框中的所有选项 for (const option of from_box.options) { const option_value = option.value; + // 如果选项在缓存中存在,则移动它 if (SelectBox.cache_contains(from, option_value)) { SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1}); SelectBox.delete_from_cache(from, option_value); } } + // 重新显示两个选择框 SelectBox.redisplay(from); SelectBox.redisplay(to); }, + + /** + * 对选择框中的选项按文本进行排序 + * @param {string} id - 选择框元素的ID + */ sort: function(id) { SelectBox.cache[id].sort(function(a, b) { a = a.text.toLowerCase(); @@ -105,12 +173,18 @@ return 0; } ); }, + + /** + * 选中选择框中的所有选项 + * @param {string} id - 选择框元素的ID + */ select_all: function(id) { const box = document.getElementById(id); + // 遍历所有选项并选中它们 for (const option of box.options) { option.selected = true; } } }; window.SelectBox = SelectBox; -} +} \ No newline at end of file diff --git a/src/collectedstatic/admin/js/SelectFilter2.js b/src/collectedstatic/admin/js/SelectFilter2.js index 970b511..9830951 100644 --- a/src/collectedstatic/admin/js/SelectFilter2.js +++ b/src/collectedstatic/admin/js/SelectFilter2.js @@ -1,38 +1,42 @@ /*global SelectBox, gettext, ngettext, interpolate, quickElement, SelectFilter*/ /* -SelectFilter2 - Turns a multiple-select box into a filter interface. +SelectFilter2 - 将多选框转换为过滤器界面。 -Requires core.js and SelectBox.js. +需要 core.js 和 SelectBox.js。 */ 'use strict'; { window.SelectFilter = { + /** + * 初始化选择过滤器 + * @param {string} field_id - 字段ID + * @param {string} field_name - 字段名称 + * @param {boolean} is_stacked - 是否堆叠显示 + */ init: function(field_id, field_name, is_stacked) { if (field_id.match(/__prefix__/)) { - // Don't initialize on empty forms. + // 不要在空表单上初始化 return; } const from_box = document.getElementById(field_id); - from_box.id += '_from'; // change its ID + from_box.id += '_from'; // 更改ID from_box.className = 'filtered'; from_box.setAttribute('aria-labelledby', field_id + '_from_title'); + // 处理from_box的兄弟元素

for (const p of from_box.parentNode.getElementsByTagName('p')) { if (p.classList.contains("info")) { - // Remove

, because it just gets in the way. + // 移除

,因为它会妨碍布局 from_box.parentNode.removeChild(p); } else if (p.classList.contains("help")) { - // Move help text up to the top so it isn't below the select - // boxes or wrapped off on the side to the right of the add - // button: + // 将帮助文本移到顶部,这样它就不会显示在选择框下方或添加按钮右侧 from_box.parentNode.insertBefore(p, from_box.parentNode.firstChild); } } - //

or
+ //
const selector_div = quickElement('div', from_box.parentNode); - // Make sure the selector div is at the beginning so that the - // add link would be displayed to the right of the widget. + // 确保选择器div在开头,这样添加链接会显示在控件的右侧 from_box.parentNode.prepend(selector_div); selector_div.className = is_stacked ? 'selector stacked' : 'selector'; @@ -50,6 +54,7 @@ Requires core.js and SelectBox.js. 'class', 'helptext' ); + // 创建过滤器输入框 const filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); filter_p.className = 'selector-filter'; @@ -67,6 +72,7 @@ Requires core.js and SelectBox.js. filter_input.id = field_id + '_input'; selector_available.appendChild(from_box); + // 创建"全选"按钮 const choose_all = quickElement( 'button', selector_available, @@ -79,6 +85,7 @@ Requires core.js and SelectBox.js. // ",{class:"select2-results__options select2-results__options--nested"});p.append(l),s.append(a),s.append(p)}else this.template(e,t);return f.StoreData(t,"data",e),t},i.prototype.bind=function(t,e){var l=this,n=t.id+"-results";this.$results.attr("id",n),t.on("results:all",function(e){l.clear(),l.append(e.data),t.isOpen()&&(l.setClasses(),l.highlightFirstItem())}),t.on("results:append",function(e){l.append(e.data),t.isOpen()&&l.setClasses()}),t.on("query",function(e){l.hideMessages(),l.showLoading(e)}),t.on("select",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("unselect",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("open",function(){l.$results.attr("aria-expanded","true"),l.$results.attr("aria-hidden","false"),l.setClasses(),l.ensureHighlightVisible()}),t.on("close",function(){l.$results.attr("aria-expanded","false"),l.$results.attr("aria-hidden","true"),l.$results.removeAttr("aria-activedescendant")}),t.on("results:toggle",function(){var e=l.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),t.on("results:select",function(){var e=l.getHighlightedResults();if(0!==e.length){var t=f.GetData(e[0],"data");"true"==e.attr("aria-selected")?l.trigger("close",{}):l.trigger("select",{data:t})}}),t.on("results:previous",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e);if(!(n<=0)){var i=n-1;0===e.length&&(i=0);var r=t.eq(i);r.trigger("mouseenter");var o=l.$results.offset().top,s=r.offset().top,a=l.$results.scrollTop()+(s-o);0===i?l.$results.scrollTop(0):s-o<0&&l.$results.scrollTop(a)}}),t.on("results:next",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e)+1;if(!(n>=t.length)){var i=t.eq(n);i.trigger("mouseenter");var r=l.$results.offset().top+l.$results.outerHeight(!1),o=i.offset().top+i.outerHeight(!1),s=l.$results.scrollTop()+o-r;0===n?l.$results.scrollTop(0):rthis.$results.outerHeight()||o<0)&&this.$results.scrollTop(r)}},i.prototype.template=function(e,t){var n=this.options.get("templateResult"),i=this.options.get("escapeMarkup"),r=n(e,t);null==r?t.style.display="none":"string"==typeof r?t.innerHTML=i(r):h(t).append(r)},i}),e.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),e.define("select2/selection/base",["jquery","../utils","../keys"],function(n,i,r){function o(e,t){this.$element=e,this.options=t,o.__super__.constructor.call(this)}return i.Extend(o,i.Observable),o.prototype.render=function(){var e=n('');return this._tabindex=0,null!=i.GetData(this.$element[0],"old-tabindex")?this._tabindex=i.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),e.attr("title",this.$element.attr("title")),e.attr("tabindex",this._tabindex),e.attr("aria-disabled","false"),this.$selection=e},o.prototype.bind=function(e,t){var n=this,i=e.id+"-results";this.container=e,this.$selection.on("focus",function(e){n.trigger("focus",e)}),this.$selection.on("blur",function(e){n._handleBlur(e)}),this.$selection.on("keydown",function(e){n.trigger("keypress",e),e.which===r.SPACE&&e.preventDefault()}),e.on("results:focus",function(e){n.$selection.attr("aria-activedescendant",e.data._resultId)}),e.on("selection:update",function(e){n.update(e.data)}),e.on("open",function(){n.$selection.attr("aria-expanded","true"),n.$selection.attr("aria-owns",i),n._attachCloseHandler(e)}),e.on("close",function(){n.$selection.attr("aria-expanded","false"),n.$selection.removeAttr("aria-activedescendant"),n.$selection.removeAttr("aria-owns"),n.$selection.trigger("focus"),n._detachCloseHandler(e)}),e.on("enable",function(){n.$selection.attr("tabindex",n._tabindex),n.$selection.attr("aria-disabled","false")}),e.on("disable",function(){n.$selection.attr("tabindex","-1"),n.$selection.attr("aria-disabled","true")})},o.prototype._handleBlur=function(e){var t=this;window.setTimeout(function(){document.activeElement==t.$selection[0]||n.contains(t.$selection[0],document.activeElement)||t.trigger("blur",e)},1)},o.prototype._attachCloseHandler=function(e){n(document.body).on("mousedown.select2."+e.id,function(e){var t=n(e.target).closest(".select2");n(".select2.select2-container--open").each(function(){this!=t[0]&&i.GetData(this,"element").select2("close")})})},o.prototype._detachCloseHandler=function(e){n(document.body).off("mousedown.select2."+e.id)},o.prototype.position=function(e,t){t.find(".selection").append(e)},o.prototype.destroy=function(){this._detachCloseHandler(this.container)},o.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},o.prototype.isEnabled=function(){return!this.isDisabled()},o.prototype.isDisabled=function(){return this.options.get("disabled")},o}),e.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n,i){function r(){r.__super__.constructor.apply(this,arguments)}return n.Extend(r,t),r.prototype.render=function(){var e=r.__super__.render.call(this);return e.addClass("select2-selection--single"),e.html(''),e},r.prototype.bind=function(t,e){var n=this;r.__super__.bind.apply(this,arguments);var i=t.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",i).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",i),this.$selection.on("mousedown",function(e){1===e.which&&n.trigger("toggle",{originalEvent:e})}),this.$selection.on("focus",function(e){}),this.$selection.on("blur",function(e){}),t.on("focus",function(e){t.isOpen()||n.$selection.trigger("focus")})},r.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},r.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},r.prototype.selectionContainer=function(){return e("")},r.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(".select2-selection__rendered"),i=this.display(t,n);n.empty().append(i);var r=t.title||t.text;r?n.attr("title",r):n.removeAttr("title")}else this.clear()},r}),e.define("select2/selection/multiple",["jquery","./base","../utils"],function(r,e,l){function n(e,t){n.__super__.constructor.apply(this,arguments)}return l.Extend(n,e),n.prototype.render=function(){var e=n.__super__.render.call(this);return e.addClass("select2-selection--multiple"),e.html('
    '),e},n.prototype.bind=function(e,t){var i=this;n.__super__.bind.apply(this,arguments),this.$selection.on("click",function(e){i.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(e){if(!i.isDisabled()){var t=r(this).parent(),n=l.GetData(t[0],"data");i.trigger("unselect",{originalEvent:e,data:n})}})},n.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},n.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},n.prototype.selectionContainer=function(){return r('
  • ×
  • ')},n.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=0;n×');a.StoreData(i[0],"data",t),this.$selection.find(".select2-selection__rendered").prepend(i)}},e}),e.define("select2/selection/search",["jquery","../utils","../keys"],function(i,a,l){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=i('');this.$searchContainer=t,this.$search=t.find("input");var n=e.call(this);return this._transferTabIndex(),n},e.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results";e.call(this,t,n),t.on("open",function(){i.$search.attr("aria-controls",r),i.$search.trigger("focus")}),t.on("close",function(){i.$search.val(""),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.trigger("focus")}),t.on("enable",function(){i.$search.prop("disabled",!1),i._transferTabIndex()}),t.on("disable",function(){i.$search.prop("disabled",!0)}),t.on("focus",function(e){i.$search.trigger("focus")}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")}),this.$selection.on("focusin",".select2-search--inline",function(e){i.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){i._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented(),e.which===l.BACKSPACE&&""===i.$search.val()){var t=i.$searchContainer.prev(".select2-selection__choice");if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("select",function(){i._checkIfMaximumSelected()})},e.prototype.query=function(e,t,n){var i=this;this._checkIfMaximumSelected(function(){e.call(i,t,n)})},e.prototype._checkIfMaximumSelected=function(e,n){var i=this;this.current(function(e){var t=null!=e?e.length:0;0=i.maximumSelectionLength?i.trigger("results:message",{message:"maximumSelected",args:{maximum:i.maximumSelectionLength}}):n&&n()})},e}),e.define("select2/dropdown",["jquery","./utils"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t('');return e.attr("dir",this.options.get("dir")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),e.define("select2/dropdown/search",["jquery","../utils"],function(o,e){function t(){}return t.prototype.render=function(e){var t=e.call(this),n=o('');return this.$searchContainer=n,this.$search=n.find("input"),t.prepend(n),t},t.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results";e.call(this,t,n),this.$search.on("keydown",function(e){i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){o(this).off("keyup")}),this.$search.on("keyup input",function(e){i.handleSearch(e)}),t.on("open",function(){i.$search.attr("tabindex",0),i.$search.attr("aria-controls",r),i.$search.trigger("focus"),window.setTimeout(function(){i.$search.trigger("focus")},0)}),t.on("close",function(){i.$search.attr("tabindex",-1),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.val(""),i.$search.trigger("blur")}),t.on("focus",function(){t.isOpen()||i.$search.trigger("focus")}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(i.showSearch(e)?i.$searchContainer.removeClass("select2-search--hide"):i.$searchContainer.addClass("select2-search--hide"))}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")})},t.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},t.prototype.showSearch=function(e,t){return!0},t}),e.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,i){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,i)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),i=t.length-1;0<=i;i--){var r=t[i];this.placeholder.id===r.id&&n.splice(i,1)}return n},e}),e.define("select2/dropdown/infiniteScroll",["jquery"],function(n){function e(e,t,n,i){this.lastParams={},e.call(this,t,n,i),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&(this.$results.append(this.$loadingMore),this.loadMoreIfNeeded())},e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("query",function(e){i.lastParams=e,i.loading=!0}),t.on("query:append",function(e){i.lastParams=e,i.loading=!0}),this.$results.on("scroll",this.loadMoreIfNeeded.bind(this))},e.prototype.loadMoreIfNeeded=function(){var e=n.contains(document.documentElement,this.$loadingMore[0]);if(!this.loading&&e){var t=this.$results.offset().top+this.$results.outerHeight(!1);this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)<=t+50&&this.loadMore()}},e.prototype.loadMore=function(){this.loading=!0;var e=n.extend({},{page:1},this.lastParams);e.page++,this.trigger("query:append",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=n('
  • '),t=this.options.get("translations").get("loadingMore");return e.html(t(this.lastParams)),e},e}),e.define("select2/dropdown/attachBody",["jquery","../utils"],function(f,a){function e(e,t,n){this.$dropdownParent=f(n.get("dropdownParent")||document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("open",function(){i._showDropdown(),i._attachPositioningHandler(t),i._bindContainerResultHandlers(t)}),t.on("close",function(){i._hideDropdown(),i._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=f(""),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._bindContainerResultHandlers=function(e,t){if(!this._containerResultsHandlersBound){var n=this;t.on("results:all",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:append",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:message",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("select",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("unselect",function(){n._positionDropdown(),n._resizeDropdown()}),this._containerResultsHandlersBound=!0}},e.prototype._attachPositioningHandler=function(e,t){var n=this,i="scroll.select2."+t.id,r="resize.select2."+t.id,o="orientationchange.select2."+t.id,s=this.$container.parents().filter(a.hasScroll);s.each(function(){a.StoreData(this,"select2-scroll-position",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),s.on(i,function(e){var t=a.GetData(this,"select2-scroll-position");f(this).scrollTop(t.y)}),f(window).on(i+" "+r+" "+o,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,i="resize.select2."+t.id,r="orientationchange.select2."+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+" "+i+" "+r)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown.hasClass("select2-dropdown--above"),n=this.$dropdown.hasClass("select2-dropdown--below"),i=null,r=this.$container.offset();r.bottom=r.top+this.$container.outerHeight(!1);var o={height:this.$container.outerHeight(!1)};o.top=r.top,o.bottom=r.top+o.height;var s=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ar.bottom+s,d={left:r.left,top:o.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h={top:0,left:0};(f.contains(document.body,p[0])||p[0].isConnected)&&(h=p.offset()),d.top-=h.top,d.left-=h.left,t||n||(i="below"),u||!c||t?!c&&u&&t&&(i="below"):i="above",("above"==i||t&&"below"!==i)&&(d.top=o.top-h.top-s),null!=i&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+i),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+i)),this.$dropdownContainer.css(d)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),e.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,i){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,i)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,i=0;i');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container.addClass("select2-container--"+this.options.get("theme")),u.StoreData(e[0],"element",this.$element),e},d}),e.define("select2/compat/utils",["jquery"],function(s){return{syncCssClasses:function(e,t,n){var i,r,o=[];(i=s.trim(e.attr("class")))&&s((i=""+i).split(/\s+/)).each(function(){0===this.indexOf("select2-")&&o.push(this)}),(i=s.trim(t.attr("class")))&&s((i=""+i).split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(r=n(this))&&o.push(r)}),e.attr("class",o.join(" "))}}}),e.define("select2/compat/containerCss",["jquery","./utils"],function(s,a){function l(e){return null}function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("containerCssClass")||"";s.isFunction(n)&&(n=n(this.$element));var i=this.options.get("adaptContainerCssClass");if(i=i||l,-1!==n.indexOf(":all:")){n=n.replace(":all:","");var r=i;i=function(e){var t=r(e);return null!=t?t+" "+e:e}}var o=this.options.get("containerCss")||{};return s.isFunction(o)&&(o=o(this.$element)),a.syncCssClasses(t,this.$element,i),t.css(o),t.addClass(n),t},e}),e.define("select2/compat/dropdownCss",["jquery","./utils"],function(s,a){function l(e){return null}function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("dropdownCssClass")||"";s.isFunction(n)&&(n=n(this.$element));var i=this.options.get("adaptDropdownCssClass");if(i=i||l,-1!==n.indexOf(":all:")){n=n.replace(":all:","");var r=i;i=function(e){var t=r(e);return null!=t?t+" "+e:e}}var o=this.options.get("dropdownCss")||{};return s.isFunction(o)&&(o=o(this.$element)),a.syncCssClasses(t,this.$element,i),t.css(o),t.addClass(n),t},e}),e.define("select2/compat/initSelection",["jquery"],function(i){function e(e,t,n){n.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=n.get("initSelection"),this._isInitialized=!1,e.call(this,t,n)}return e.prototype.current=function(e,t){var n=this;this._isInitialized?e.call(this,t):this.initSelection.call(null,this.$element,function(e){n._isInitialized=!0,i.isArray(e)||(e=[e]),t(e)})},e}),e.define("select2/compat/inputData",["jquery","../utils"],function(s,i){function e(e,t,n){this._currentData=[],this._valueSeparator=n.get("valueSeparator")||",","hidden"===t.prop("type")&&n.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `');this.$searchContainer=t,this.$search=t.find("input");var n=e.call(this);return this._transferTabIndex(),n},e.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results";e.call(this,t,n),t.on("open",function(){i.$search.attr("aria-controls",r),i.$search.trigger("focus")}),t.on("close",function(){i.$search.val(""),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.trigger("focus")}),t.on("enable",function(){i.$search.prop("disabled",!1),i._transferTabIndex()}),t.on("disable",function(){i.$search.prop("disabled",!0)}),t.on("focus",function(e){i.$search.trigger("focus")}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")}),this.$selection.on("focusin",".select2-search--inline",function(e){i.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){i._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented(),e.which===l.BACKSPACE&&""===i.$search.val()){var t=i.$searchContainer.prev(".select2-selection__choice");if(0= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } - +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"]; if (!it) { if (_Array$isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = +method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { var _context4; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = _sliceInstanceProperty(_context4 = Object.prototype.toString.call(o)).call(_context4, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } @@ -40,41 +39,40 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len * * Steven Levithan (c) 2008-present MIT License */ +// XRegExp是一个增强的JavaScript正则表达式库 +// 此文件是XRegExp的Unicode基础模块,提供对Unicode匹配的支持 + var _default = function _default(XRegExp) { /** - * Adds base support for Unicode matching: - * - Adds syntax `\p{..}` for matching Unicode tokens. Tokens can be inverted using `\P{..}` or - * `\p{^..}`. Token names ignore case, spaces, hyphens, and underscores. You can omit the - * braces for token names that are a single letter (e.g. `\pL` or `PL`). - * - Adds flag A (astral), which enables 21-bit Unicode support. - * - Adds the `XRegExp.addUnicodeData` method used by other addons to provide character data. + * 添加对Unicode匹配的基础支持: + * - 添加语法 `\p{..}` 用于匹配Unicode标记。可以通过 `\P{..}` 或 `\p{^..}` 反转标记。 + * 标记名称忽略大小写、空格、连字符和下划线。对于单字母标记名称可以省略大括号(例如 `\pL` 或 `PL`)。 + * - 添加标志A(astral),启用21位Unicode支持。 + * - 添加 `XRegExp.addUnicodeData` 方法,由其他插件用于提供字符数据。 * - * Unicode Base relies on externally provided Unicode character data. Official addons are - * available to provide data for Unicode categories, scripts, and properties. + * Unicode Base依赖于外部提供的Unicode字符数据。官方插件可用于提供Unicode类别、脚本和属性的数据。 * * @requires XRegExp */ // ==--------------------------== - // Private stuff + // 私有内容 // ==--------------------------== - // Storage for Unicode data + // Unicode数据存储 var unicode = {}; - var unicodeTypes = {}; // Reuse utils + var unicodeTypes = {}; // 重用工具函数 var dec = XRegExp._dec; var hex = XRegExp._hex; - var pad4 = XRegExp._pad4; // Generates a token lookup name: lowercase, with hyphens, spaces, and underscores removed + var pad4 = XRegExp._pad4; // 生成标记查找名称:小写,去除连字符、空格和下划线 function normalize(name) { return name.replace(/[- _]+/g, '').toLowerCase(); - } // Gets the decimal code of a literal code unit, \xHH, \uHHHH, or a backslash-escaped literal - + } // 获取文字代码单元、\xHH、\uHHHH或反斜杠转义文字的十进制代码 function charCode(chr) { var esc = /^\\[xu](.+)/.exec(chr); return esc ? dec(esc[1]) : chr.charCodeAt(chr[0] === '\\' ? 1 : 0); - } // Inverts a list of ordered BMP characters and ranges - + } // 反转有序BMP字符和范围列表 function invertBmp(range) { var output = ''; @@ -102,14 +100,12 @@ var _default = function _default(XRegExp) { } return output; - } // Generates an inverted BMP range on first use - + } // 首次使用时生成反转的BMP范围 function cacheInvertedBmp(slug) { var prop = 'b!'; return unicode[slug][prop] || (unicode[slug][prop] = invertBmp(unicode[slug].bmp)); - } // Combines and optionally negates BMP and astral data - + } // 组合并可选地否定BMP和astral数据 function buildAstral(slug, isNegated) { var item = unicode[slug]; @@ -129,27 +125,25 @@ var _default = function _default(XRegExp) { var _context2; combined += (0, _concat["default"])(_context2 = "".concat(item.astral ? '|' : '', "[")).call(_context2, item.bmp, "]"); - } // Astral Unicode tokens always match a code point, never a code unit - + } // Astral Unicode标记始终匹配码点,从不匹配码元 return isNegated ? "(?:(?!".concat(combined, ")(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[\0-\uFFFF]))") : "(?:".concat(combined, ")"); - } // Builds a complete astral pattern on first use - + } // 首次使用时构建完整的astral模式 function cacheAstral(slug, isNegated) { var prop = isNegated ? 'a!' : 'a='; return unicode[slug][prop] || (unicode[slug][prop] = buildAstral(slug, isNegated)); } // ==--------------------------== - // Core functionality + // 核心功能 // ==--------------------------== /* - * Add astral mode (flag A) and Unicode token syntax: `\p{..}`, `\P{..}`, `\p{^..}`, `\pC`. + * 添加astral模式(标志A)和Unicode标记语法:`\p{..}`、`\P{..}`、`\p{^..}`、`\pC`。 */ - XRegExp.addToken( // Use `*` instead of `+` to avoid capturing `^` as the token name in `\p{^}` - /\\([pP])(?:{(\^?)(?:(\w+)=)?([^}]*)}|([A-Za-z]))/, function (match, scope, flags) { + XRegExp.addToken( // 使用`*`而不是`+`避免将`^`捕获为标记名称在`\p{^}` +/\\([pP])(?:{(\^?)(?:(\w+)=)?([^}]*)}|([A-Za-z]))/, function (match, scope, flags) { var ERR_DOUBLE_NEG = 'Invalid double negation '; var ERR_UNKNOWN_NAME = 'Unknown Unicode token '; var ERR_UNKNOWN_REF = 'Unicode token missing data '; @@ -162,15 +156,13 @@ var _default = function _default(XRegExp) { caretNegation = _match[2], typePrefix = _match[3], tokenName = _match[4], - tokenSingleCharName = _match[5]; // Negated via \P{..} or \p{^..} + tokenSingleCharName = _match[5]; // 通过\P{..}或\p{^..}否定 + var isNegated = pPrefix === 'P' || !!caretNegation; // 通过标志A从BMP(0-FFFF)切换到astral(0-10FFFF)模式 - var isNegated = pPrefix === 'P' || !!caretNegation; // Switch from BMP (0-FFFF) to astral (0-10FFFF) mode via flag A + var isAstralMode = (0, _indexOf["default"])(flags).call(flags, 'A') !== -1; // 标记查找名称。首先检查`tokenSingleCharName`以避免传递`undefined` - var isAstralMode = (0, _indexOf["default"])(flags).call(flags, 'A') !== -1; // Token lookup name. Check `tokenSingleCharName` first to avoid passing `undefined` - // via `\p{}` - - var slug = normalize(tokenSingleCharName || tokenName); // Token data object + var slug = normalize(tokenSingleCharName || tokenName); // 标记数据对象 var item = unicode[slug]; @@ -186,14 +178,14 @@ var _default = function _default(XRegExp) { if (!(unicodeTypes[typePrefix] && unicodeTypes[typePrefix][slug])) { throw new SyntaxError(ERR_UNKNOWN_NAME + fullToken); } - } // Switch to the negated form of the referenced Unicode token - + } // 切换到引用的Unicode标记的否定形式 if (item.inverseOf) { slug = normalize(item.inverseOf); if (!unicode.hasOwnProperty(slug)) { var _context3; +var _context3; throw new ReferenceError((0, _concat["default"])(_context3 = "".concat(ERR_UNKNOWN_REF + fullToken, " -> ")).call(_context3, item.inverseOf)); } @@ -221,29 +213,29 @@ var _default = function _default(XRegExp) { leadChar: '\\' }); /** - * Adds to the list of Unicode tokens that XRegExp regexes can match via `\p` or `\P`. +leadChar: '\\' + }); + /** + * 添加到XRegExp正则表达式可通过`\p`或`\P`匹配的Unicode标记列表中。 * * @memberOf XRegExp - * @param {Array} data Objects with named character ranges. Each object may have properties - * `name`, `alias`, `isBmpLast`, `inverseOf`, `bmp`, and `astral`. All but `name` are - * optional, although one of `bmp` or `astral` is required (unless `inverseOf` is set). If - * `astral` is absent, the `bmp` data is used for BMP and astral modes. If `bmp` is absent, - * the name errors in BMP mode but works in astral mode. If both `bmp` and `astral` are - * provided, the `bmp` data only is used in BMP mode, and the combination of `bmp` and - * `astral` data is used in astral mode. `isBmpLast` is needed when a token matches orphan - * high surrogates *and* uses surrogate pairs to match astral code points. The `bmp` and - * `astral` data should be a combination of literal characters and `\xHH` or `\uHHHH` escape - * sequences, with hyphens to create ranges. Any regex metacharacters in the data should be - * escaped, apart from range-creating hyphens. The `astral` data can additionally use - * character classes and alternation, and should use surrogate pairs to represent astral code - * points. `inverseOf` can be used to avoid duplicating character data if a Unicode token is - * defined as the exact inverse of another token. - * @param {String} [typePrefix] Enables optionally using this type as a prefix for all of the - * provided Unicode tokens, e.g. if given `'Type'`, then `\p{TokenName}` can also be written - * as `\p{Type=TokenName}`. + * @param {Array} data 带有命名字符范围的对象。每个对象可以有属性 + * `name`、`alias`、`isBmpLast`、`inverseOf`、`bmp`和`astral`。除了`name`之外都是 + * 可选的,尽管需要`bmp`或`astral`之一(除非设置了`inverseOf`)。如果 + * 缺少`astral`,则在BMP和astral模式下都使用`bmp`数据。如果缺少`bmp`, + * 在BMP模式下名称会出错但在astral模式下有效。如果同时提供了`bmp`和`astral`, + * 在BMP模式下仅使用`bmp`数据,在astral模式下结合使用`bmp`和`astral`数据。当标记匹配孤儿 + * 高代理项*并且*使用代理对匹配astral码点时,需要`isBmpLast`。`bmp`和 + * `astral`数据应该是文字字符和`\xHH`或`\uHHHH`转义序列的组合, + * 使用连字符创建范围。数据中的任何正则元字符都应该被转义,除了创建范围的连字符。`astral`数据可以额外使用 + * 字符类和替代,并应使用代理对表示astral码点。`inverseOf`可用于避免重复字符数据,如果Unicode标记被定义为另一个标记的精确反向时使用。 + * @param {String} [typePrefix] 启用可选地使用此类型作为所有提供的Unicode标记的前缀,例如如果给定`'Type'`,则`\p{TokenName}`也可以写成`\p{Type=TokenName}`。 * @example * - * // Basic use + * // 基本使用 +* @example + * + * // 基本使用 * XRegExp.addUnicodeData([{ * name: 'XDigit', * alias: 'Hexadecimal', @@ -257,7 +249,7 @@ var _default = function _default(XRegExp) { var ERR_NO_DATA = 'Unicode token has no character data '; if (typePrefix) { - // Case sensitive to match ES2018 + // 区分大小写以匹配ES2018 unicodeTypes[typePrefix] = {}; } @@ -271,6 +263,8 @@ var _default = function _default(XRegExp) { if (!item.name) { throw new Error(ERR_NO_NAME); } +throw new Error(ERR_NO_NAME); + } if (!(item.inverseOf || item.bmp || item.astral)) { throw new Error(ERR_NO_DATA + item.name); @@ -291,8 +285,7 @@ var _default = function _default(XRegExp) { unicodeTypes[typePrefix][normalizedAlias] = true; } } - } // Reset the pattern cache used by the `XRegExp` constructor, since the same pattern and - // flags might now produce different results + } // 重置由`XRegExp`构造函数使用的模式缓存,因为相同的模式和标志现在可能产生不同的结果 } catch (err) { _iterator.e(err); @@ -305,23 +298,22 @@ var _default = function _default(XRegExp) { /** * @ignore * - * Return a reference to the internal Unicode definition structure for the given Unicode - * Property if the given name is a legal Unicode Property for use in XRegExp `\p` or `\P` regex - * constructs. +}; + /** + * @ignore + * + * 返回给定Unicode属性的内部Unicode定义结构的引用,如果给定名称是XRegExp `\p`或`\P`正则表达式构造中合法的Unicode属性的话。 * * @memberOf XRegExp - * @param {String} name Name by which the Unicode Property may be recognized (case-insensitive), - * e.g. `'N'` or `'Number'`. The given name is matched against all registered Unicode - * Properties and Property Aliases. - * @returns {Object} Reference to definition structure when the name matches a Unicode Property. + * @param {String} name 可识别Unicode属性的名称(不区分大小写),例如`'N'`或`'Number'`。给定名称与所有已注册的Unicode属性和属性别名匹配。 + * @returns {Object} 当名称匹配Unicode属性时返回定义结构的引用。 * * @note - * For more info on Unicode Properties, see also http://unicode.org/reports/tr18/#Categories. + * 更多关于Unicode属性的信息,请参见 http://unicode.org/reports/tr18/#Categories. * * @note - * This method is *not* part of the officially documented API and may change or be removed in - * the future. It is meant for userland code that wishes to reuse the (large) internal Unicode - * structures set up by XRegExp. + * 此方法*不是*官方文档API的一部分,将来可能会更改或被删除。它适用于希望重用XRegExp设置的大量内部Unicode结构的用户代码。 +* structures set up by XRegExp. */ @@ -356,11 +348,11 @@ var _categories = _interopRequireDefault(require("../../tools/output/categories" */ var _default = function _default(XRegExp) { /** - * Adds support for Unicode's general categories. E.g., `\p{Lu}` or `\p{Uppercase Letter}`. See - * category descriptions in UAX #44 . Token - * names are case insensitive, and any spaces, hyphens, and underscores are ignored. + * 添加对Unicode通用类别的支持。例如,`\p{Lu}`或`\p{Uppercase Letter}`。请参阅 + * UAX #44 中的类别描述。标记 +* 名称不区分大小写,并忽略任何空格、连字符和下划线。 * - * Uses Unicode 14.0.0. + * 使用Unicode 14.0.0. * * @requires XRegExp, Unicode Base */ @@ -383,6 +375,8 @@ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequ _Object$defineProperty(exports, "__esModule", { value: true }); +value: true +}); exports["default"] = void 0; @@ -403,7 +397,6 @@ module.exports = exports.default; var _sliceInstanceProperty2 = require("@babel/runtime-corejs3/core-js-stable/instance/slice"); var _Array$from = require("@babel/runtime-corejs3/core-js-stable/array/from"); - var _Symbol = require("@babel/runtime-corejs3/core-js-stable/symbol"); var _getIteratorMethod = require("@babel/runtime-corejs3/core-js/get-iterator-method"); @@ -427,7 +420,6 @@ var _flags = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stab var _sort = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/sort")); var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice")); - var _parseInt2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/parse-int")); var _indexOf = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/index-of")); @@ -437,9 +429,8 @@ var _forEach = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-st var _create = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/create")); var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat")); - -function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"]; if (!it) { if (_Array$isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } - +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"]; if (!it) { if (_Array$isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = +method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { var _context9; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = _sliceInstanceProperty2(_context9 = Object.prototype.toString.call(o)).call(_context9, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } @@ -451,29 +442,38 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len */ /** - * XRegExp provides augmented, extensible regular expressions. You get additional regex syntax and - * flags, beyond what browsers support natively. XRegExp is also a regex utility belt with tools to - * make your client-side grepping simpler and more powerful, while freeing you from related - * cross-browser inconsistencies. +*/ + +/** + * XRegExp提供增强的、可扩展的正则表达式。您可以获得额外的正则表达式语法和标志,超出浏览器原生支持的范围。XRegExp还是一个正则表达式工具带,使您的客户端搜索更简单、更强大,同时免受相关的跨浏览器不一致性的影响。 */ // ==--------------------------== -// Private stuff +// 私有内容 // ==--------------------------== -// Property name used for extended regex instance data -var REGEX_DATA = 'xregexp'; // Optional features that can be installed and uninstalled +// 用于扩展正则表达式实例数据的属性名 +var REGEX_DATA = 'xregexp'; // 可安装和卸载的可选功能 var features = { astral: false, namespacing: true -}; // Storage for fixed/extended native methods +}; // 固定/扩展的原生方法存储 + +var fixed = {}; // 由`XRegExp.cache`缓存的正则表达式存储 -var fixed = {}; // Storage for regexes cached by `XRegExp.cache` +var regexCache = {}; // 由`XRegExp`构造函数缓存的模式详细信息存储 -var regexCache = {}; // Storage for pattern details cached by the `XRegExp` constructor +var patternCache = {}; // 由内部或`XRegExp.addToken`添加的正则表达式语法标记存储 -var patternCache = {}; // Storage for regex syntax tokens added internally or by `XRegExp.addToken` +var tokens = []; // 标记作用域 -var tokens = []; // Token scopes +var defaultScope = 'default'; +var classScope = 'class'; // 匹配原生正则表达式语法的正则表达式,包括八进制 + +var nativeTokens = { + // 默认作用域中的任何原生多字符标记,或任何单个字符 + 'default': /\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u(?:[\dA-Fa-f]{4}|{[\dA-Fa-f]+})|c[A-Za-z]|[\s\S])|\(\?(?:[:=!]|<[=!])|[?*+]\?|{\d+(?:,\d*)?}\??|[\s\S]/, + // 字符类作用域中的任何原生多字符标记,或任何单个字符 + 'class': /\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u(?:[\dA-Fa-f]{4}|{[\dA-Fa-f]+})|c[A-Za-z]|[\s\S])|[\s\S]/``` var defaultScope = 'default'; var classScope = 'class'; // Regexes that match native regex syntax, including octals diff --git a/src/collectedstatic/assets/css/signin.css b/src/collectedstatic/assets/css/signin.css index 121fb0d..0edc17d 100644 --- a/src/collectedstatic/assets/css/signin.css +++ b/src/collectedstatic/assets/css/signin.css @@ -1,58 +1,78 @@ +/* 登录页面样式 */ body { - padding-top: 40px; - padding-bottom: 40px; - background-color: #fff; + padding-top: 40px; /* 顶部内边距 */ + padding-bottom: 40px; /* 底部内边距 */ + background-color: #fff; /* 背景颜色为白色 */ } +/* 登录表单样式 */ .form-signin { - max-width: 330px; - padding: 15px; - margin: 0 auto; + max-width: 330px; /* 最大宽度 */ + padding: 15px; /* 内边距 */ + margin: 0 auto; /* 居中显示 */ } + +/* 登录表单标题样式 */ .form-signin-heading { - margin: 0 0 15px; - font-size: 18px; - font-weight: 400; - color: #555; + margin: 0 0 15px; /* 外边距 */ + font-size: 18px; /* 字体大小 */ + font-weight: 400; /* 字体粗细 */ + color: #555; /* 字体颜色 */ } + +/* 复选框样式 */ .form-signin .checkbox { - margin-bottom: 10px; - font-weight: normal; + margin-bottom: 10px; /* 底部外边距 */ + font-weight: normal; /* 正常字体粗细 */ } + +/* 表单控件通用样式 */ .form-signin .form-control { - position: relative; - height: auto; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 10px; - font-size: 16px; + position: relative; /* 相对定位 */ + height: auto; /* 自动高度 */ + -webkit-box-sizing: border-box; /* Webkit浏览器盒模型 */ + -moz-box-sizing: border-box; /* Mozilla浏览器盒模型 */ + box-sizing: border-box; /* 标准盒模型 */ + padding: 10px; /* 内边距 */ + font-size: 16px; /* 字体大小 */ } + +/* 表单控件获得焦点时的样式 */ .form-signin .form-control:focus { - z-index: 2; + z-index: 2; /* 层级 */ } + +/* 邮箱输入框样式 */ .form-signin input[type="email"] { - margin-bottom: 10px; + margin-bottom: 10px; /* 底部外边距 */ } + +/* 密码输入框样式 */ .form-signin input[type="password"] { - margin-bottom: 10px; + margin-bottom: 10px; /* 底部外边距 */ } + +/* 卡片容器样式 */ .card { - width: 304px; - padding: 20px 25px 30px; - margin: 0 auto 25px; - background-color: #f7f7f7; - border-radius: 2px; - -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, .3); - box-shadow: 0 2px 2px rgba(0, 0, 0, .3); + width: 304px; /* 宽度 */ + padding: 20px 25px 30px; /* 内边距:上20px,左右25px,下30px */ + margin: 0 auto 25px; /* 居中显示,底部外边距25px */ + background-color: #f7f7f7; /* 背景颜色 */ + border-radius: 2px; /* 圆角 */ + -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, .3); /* Webkit浏览器阴影 */ + box-shadow: 0 2px 2px rgba(0, 0, 0, .3); /* 标准阴影 */ } + +/* 登录卡片样式 */ .card-signin { - width: 354px; - padding: 40px; + width: 354px; /* 宽度 */ + padding: 40px; /* 内边距 */ } + +/* 登录卡片中的头像图片样式 */ .card-signin .profile-img { - display: block; - width: 96px; - height: 96px; - margin: 0 auto 10px; -} + display: block; /* 显示为块级元素 */ + width: 96px; /* 宽度 */ + height: 96px; /* 高度 */ + margin: 0 auto 10px; /* 居中显示,底部外边距10px */ +} \ No newline at end of file diff --git a/src/collectedstatic/blog/css/ie.css b/src/collectedstatic/blog/css/ie.css index 706f510..b202c60 100644 --- a/src/collectedstatic/blog/css/ie.css +++ b/src/collectedstatic/blog/css/ie.css @@ -1,13 +1,18 @@ /* -Styles for older IE versions (previous to IE9). +针对旧版IE浏览器(IE9之前版本)的样式 */ +/* 页面主体背景色 */ body { background-color: #e6e6e6; } + +/* 自定义背景为空时的样式 */ body.custom-background-empty { background-color: #fff; } + +/* 自定义背景为空或白色时站点样式 */ body.custom-background-empty .site, body.custom-background-white .site { box-shadow: none; @@ -15,14 +20,20 @@ body.custom-background-white .site { margin-top: 0; padding: 0; } + +/* 辅助文本和屏幕阅读器文本 */ .assistive-text, .site .screen-reader-text { clip: rect(1px 1px 1px 1px); } + +/* 全宽页面内容 */ .full-width .site-content { float: none; width: 100%; } + +/* 防止IE8中具有高度和宽度属性的完整尺寸和大尺寸图像被拉伸 */ img.size-full, img.size-large, img.header-image, @@ -30,17 +41,23 @@ img.wp-post-image, img[class*="align"], img[class*="wp-image-"], img[class*="attachment-"] { - width: auto; /* Prevent stretching of full-size and large-size images with height and width attributes in IE8 */ + width: auto; /* 防止在IE8中拉伸完整尺寸和大尺寸图像 */ } + +/* 作者头像 */ .author-avatar { float: left; margin-top: 8px; margin-top: 0.571428571rem; } + +/* 作者描述 */ .author-description { float: right; width: 80%; } + +/* 站点容器 */ .site { box-shadow: 0 2px 6px rgba(100, 100, 100, 0.3); margin: 48px auto; @@ -48,27 +65,39 @@ img[class*="attachment-"] { overflow: hidden; padding: 0 40px; } + +/* 站点内容 */ .site-content { float: left; width: 65.104166667%; } + +/* 不同页面模板的站点内容宽度 */ body.template-front-page .site-content, body.attachment .site-content, body.full-width .site-content { width: 100%; } + +/* 小工具区域 */ .widget-area { float: right; width: 26.041666667%; } + +/* 站点头部标题 */ .site-header h1, .site-header h2 { text-align: left; } + +/* 站点头部一级标题 */ .site-header h1 { font-size: 26px; line-height: 1.846153846; } + +/* 主导航菜单 */ .main-navigation ul.nav-menu, .main-navigation div.nav-menu > ul { border-bottom: 1px solid #ededed; @@ -77,32 +106,46 @@ body.full-width .site-content { text-align: left; width: 100%; } + +/* 主导航菜单列表 */ .main-navigation ul { margin: 0; text-indent: 0; } + +/* 主导航菜单项和链接 */ .main-navigation li a, .main-navigation li { display: inline-block; text-decoration: none; } + +/* IE7浏览器特殊处理 */ .ie7 .main-navigation li a, .ie7 .main-navigation li { display: inline; } + +/* 主导航菜单链接 */ .main-navigation li a { border-bottom: 0; color: #6a6a6a; line-height: 3.692307692; text-transform: uppercase; } + +/* 主导航菜单链接悬停效果 */ .main-navigation li a:hover { color: #000; } + +/* 主导航菜单项 */ .main-navigation li { margin: 0 40px 0 0; position: relative; } + +/* 主导航菜单下拉列表 */ .main-navigation li ul { margin: 0; padding: 0; @@ -114,17 +157,23 @@ body.full-width .site-content { overflow: hidden; clip: rect(1px, 1px, 1px, 1px); } + +/* IE7浏览器下拉列表特殊处理 */ .ie7 .main-navigation li ul { clip: inherit; display: none; left: 0; overflow: visible; } + +/* 多级下拉菜单 */ .main-navigation li ul ul, .ie7 .main-navigation li ul ul { top: 0; left: 100%; } + +/* 下拉菜单显示 */ .main-navigation ul li:hover > ul, .main-navigation ul li:focus > ul, .main-navigation .focus > ul { @@ -134,10 +183,14 @@ body.full-width .site-content { height: inherit; width: inherit; } + +/* IE7浏览器下拉菜单显示特殊处理 */ .ie7 .main-navigation ul li:hover > ul, .ie7 .main-navigation ul li:focus > ul { display: block; } + +/* 下拉菜单项链接 */ .main-navigation li ul li a { background: #efefef; border-bottom: 1px solid #ededed; @@ -147,10 +200,14 @@ body.full-width .site-content { padding: 8px 10px; width: 180px; } + +/* 下拉菜单项链接悬停效果 */ .main-navigation li ul li a:hover { background: #e3e3e3; color: #444; } + +/* 当前菜单项样式 */ .main-navigation .current-menu-item > a, .main-navigation .current-menu-ancestor > a, .main-navigation .current_page_item > a, @@ -158,39 +215,58 @@ body.full-width .site-content { color: #636363; font-weight: bold; } + +/* 菜单切换按钮 */ .main-navigation .menu-toggle { display: none; } + +/* 文章标题 */ .entry-header .entry-title { font-size: 22px; } + +/* 评论表单输入框 */ #respond form input[type="text"] { width: 46.333333333%; } + +/* 评论表单文本域 */ #respond form textarea.blog-textarea { width: 79.666666667%; } + +/* 首页模板内容 */ .template-front-page .site-content, .template-front-page article { overflow: hidden; } + +/* 首页模板带缩略图文章 */ .template-front-page.has-post-thumbnail article { float: left; width: 47.916666667%; } + +/* 页面图像 */ .entry-page-image { float: right; margin-bottom: 0; width: 47.916666667%; } -/* IE Front Page Template Widget fix */ + +/* IE首页模板小工具修复 */ .template-front-page .widget-area { clear: both; } + +/* 首页模板小工具 */ .template-front-page .widget { width: 100% !important; border: none; } + +/* 首页模板小工具区域 */ .template-front-page .widget-area .widget, .template-front-page .first.front-widgets, .template-front-page.two-sidebars .widget-area .front-widgets { @@ -198,10 +274,14 @@ body.full-width .site-content { margin-bottom: 24px; width: 51.875%; } + +/* 首页模板第二组小工具 */ .template-front-page .second.front-widgets, .template-front-page .widget-area .widget:nth-child(odd) { clear: right; } + +/* 首页模板第一组和第二组小工具 */ .template-front-page .first.front-widgets, .template-front-page .second.front-widgets, .template-front-page.two-sidebars .widget-area .front-widgets + .front-widgets { @@ -209,64 +289,88 @@ body.full-width .site-content { margin: 0 0 24px; width: 39.0625%; } + +/* 双侧边栏模板小工具 */ .template-front-page.two-sidebars .widget, .template-front-page.two-sidebars .widget:nth-child(even) { float: none; width: auto; } -/* add input font for ul { text-align: right; } + +/* RTL布局多级导航菜单项 */ .rtl .main-navigation ul li ul li, .rtl .main-navigation ul li ul li ul li { margin-left: 40px; margin-right: auto; } + +/* RTL布局三级导航菜单 */ .rtl .main-navigation li ul ul { position: absolute; bottom: 0; right: 100%; z-index: 1; } + +/* IE7浏览器RTL布局三级导航菜单特殊处理 */ .ie7 .rtl .main-navigation li ul ul { position: absolute; bottom: 0; right: 100%; z-index: 1; } + +/* IE7浏览器RTL布局导航菜单项 */ .ie7 .rtl .main-navigation ul li { z-index: 99; } + +/* IE7浏览器RTL布局下拉菜单 */ .ie7 .rtl .main-navigation li ul { position: absolute; bottom: 100%; right: 0; z-index: 1; } + +/* IE7浏览器RTL布局导航菜单项外边距 */ .ie7 .rtl .main-navigation li { margin-right: auto; margin-left: 40px; } + +/* IE7浏览器RTL布局四级导航菜单 */ .ie7 .rtl .main-navigation li ul ul ul { position: relative; z-index: 1; diff --git a/src/collectedstatic/blog/css/nprogress.css b/src/collectedstatic/blog/css/nprogress.css index 90c7b6c..b37042e 100644 --- a/src/collectedstatic/blog/css/nprogress.css +++ b/src/collectedstatic/blog/css/nprogress.css @@ -1,10 +1,11 @@ -/* Make clicks pass-through */ +/* 使点击事件穿透 */ #nprogress { pointer-events: none; } +/* 进度条样式 */ #nprogress .bar { - background: red; + background: red; /* 进度条颜色 */ position: fixed; z-index: 1031; @@ -15,7 +16,7 @@ height: 2px; } -/* Fancy blur effect */ +/* 花哨的模糊效果 */ #nprogress .peg { display: block; position: absolute; @@ -30,7 +31,7 @@ transform: rotate(3deg) translate(0px, -4px); } -/* Remove these to get rid of the spinner */ +/* 移除这些来去掉旋转器 */ #nprogress .spinner { display: block; position: fixed; @@ -39,6 +40,7 @@ right: 15px; } +/* 旋转器图标样式 */ #nprogress .spinner-icon { width: 18px; height: 18px; @@ -53,22 +55,26 @@ animation: nprogress-spinner 400ms linear infinite; } +/* 自定义父容器样式 */ .nprogress-custom-parent { overflow: hidden; position: relative; } +/* 自定义父容器中的旋转器和进度条样式 */ .nprogress-custom-parent #nprogress .spinner, .nprogress-custom-parent #nprogress .bar { position: absolute; } +/* Webkit内核浏览器的旋转器动画 */ @-webkit-keyframes nprogress-spinner { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } + +/* 标准旋转器动画 */ @keyframes nprogress-spinner { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } -} - +} \ No newline at end of file diff --git a/src/collectedstatic/blog/css/oauth_style.css b/src/collectedstatic/blog/css/oauth_style.css index 8af78af..0f151cf 100644 --- a/src/collectedstatic/blog/css/oauth_style.css +++ b/src/collectedstatic/blog/css/oauth_style.css @@ -1,173 +1,212 @@ - +/* Google图标样式 */ .icon-sn-google { background-position: 0 -28px; } +/* Google背景图标样式 */ .icon-sn-bg-google { background-color: #4285f4; background-position: 0 0; } +/* Google字体图标颜色 */ .fa-sn-google { color: #4285f4; } +/* GitHub图标样式 */ .icon-sn-github { background-position: -28px -28px; } +/* GitHub背景图标样式 */ .icon-sn-bg-github { background-color: #333; background-position: -28px 0; } +/* GitHub字体图标颜色 */ .fa-sn-github { color: #333; } +/* 微博图标样式 */ .icon-sn-weibo { background-position: -56px -28px; } +/* 微博背景图标样式 */ .icon-sn-bg-weibo { background-color: #e90d24; background-position: -56px 0; } +/* 微博字体图标颜色 */ .fa-sn-weibo { color: #e90d24; } +/* QQ图标样式 */ .icon-sn-qq { background-position: -84px -28px; } +/* QQ背景图标样式 */ .icon-sn-bg-qq { background-color: #0098e6; background-position: -84px 0; } +/* QQ字体图标颜色 */ .fa-sn-qq { color: #0098e6; } +/* Twitter图标样式 */ .icon-sn-twitter { background-position: -112px -28px; } +/* Twitter背景图标样式 */ .icon-sn-bg-twitter { background-color: #50abf1; background-position: -112px 0; } +/* Twitter字体图标颜色 */ .fa-sn-twitter { color: #50abf1; } +/* Facebook图标样式 */ .icon-sn-facebook { background-position: -140px -28px; } +/* Facebook背景图标样式 */ .icon-sn-bg-facebook { background-color: #4862a3; background-position: -140px 0; } +/* Facebook字体图标颜色 */ .fa-sn-facebook { color: #4862a3; } +/* 人人网图标样式 */ .icon-sn-renren { background-position: -168px -28px; } +/* 人人网背景图标样式 */ .icon-sn-bg-renren { background-color: #197bc8; background-position: -168px 0; } +/* 人人网字体图标颜色 */ .fa-sn-renren { color: #197bc8; } +/* 腾讯微博图标样式 */ .icon-sn-tqq { background-position: -196px -28px; } +/* 腾讯微博背景图标样式 */ .icon-sn-bg-tqq { background-color: #1f9ed2; background-position: -196px 0; } +/* 腾讯微博字体图标颜色 */ .fa-sn-tqq { color: #1f9ed2; } +/* 豆瓣图标样式 */ .icon-sn-douban { background-position: -224px -28px; } +/* 豆瓣背景图标样式 */ .icon-sn-bg-douban { background-color: #279738; background-position: -224px 0; } +/* 豆瓣字体图标颜色 */ .fa-sn-douban { color: #279738; } +/* 微信图标样式 */ .icon-sn-weixin { background-position: -252px -28px; } +/* 微信背景图标样式 */ .icon-sn-bg-weixin { background-color: #00b500; background-position: -252px 0; } +/* 微信字体图标颜色 */ .fa-sn-weixin { color: #00b500; } +/* 虚线图标样式 */ .icon-sn-dotted { background-position: -280px -28px; } +/* 虚线背景图标样式 */ .icon-sn-bg-dotted { background-color: #eee; background-position: -280px 0; } +/* 虚线字体图标颜色 */ .fa-sn-dotted { color: #eee; } +/* 网站图标样式 */ .icon-sn-site { background-position: -308px -28px; } +/* 网站背景图标样式 */ .icon-sn-bg-site { background-color: #00b500; background-position: -308px 0; } +/* 网站字体图标颜色 */ .fa-sn-site { color: #00b500; } +/* LinkedIn图标样式 */ .icon-sn-linkedin { background-position: -336px -28px; } +/* LinkedIn背景图标样式 */ .icon-sn-bg-linkedin { background-color: #0077b9; background-position: -336px 0; } +/* LinkedIn字体图标颜色 */ .fa-sn-linkedin { color: #0077b9; } +/* 社交网络图标通用样式 */ [class*=icon-sn-] { display: inline-block; background-image: url('../img/icon-sn.svg'); @@ -178,128 +217,159 @@ background-size: auto 56px; } +/* 社交网络图标悬停效果 */ [class*=icon-sn-]:hover { opacity: .8; filter: alpha(opacity=80); } +/* Google按钮样式 */ .btn-sn-google { background: #4285f4; } +/* Google按钮激活、聚焦、悬停样式 */ .btn-sn-google:active, .btn-sn-google:focus, .btn-sn-google:hover { background: #2a75f3; } +/* GitHub按钮样式 */ .btn-sn-github { background: #333; } +/* GitHub按钮激活、聚焦、悬停样式 */ .btn-sn-github:active, .btn-sn-github:focus, .btn-sn-github:hover { background: #262626; } +/* 微博按钮样式 */ .btn-sn-weibo { background: #e90d24; } +/* 微博按钮激活、聚焦、悬停样式 */ .btn-sn-weibo:active, .btn-sn-weibo:focus, .btn-sn-weibo:hover { background: #d10c20; } +/* QQ按钮样式 */ .btn-sn-qq { background: #0098e6; } +/* QQ按钮激活、聚焦、悬停样式 */ .btn-sn-qq:active, .btn-sn-qq:focus, .btn-sn-qq:hover { background: #0087cd; } +/* Twitter按钮样式 */ .btn-sn-twitter { background: #50abf1; } +/* Twitter按钮激活、聚焦、悬停样式 */ .btn-sn-twitter:active, .btn-sn-twitter:focus, .btn-sn-twitter:hover { background: #38a0ef; } +/* Facebook按钮样式 */ .btn-sn-facebook { background: #4862a3; } +/* Facebook按钮激活、聚焦、悬停样式 */ .btn-sn-facebook:active, .btn-sn-facebook:focus, .btn-sn-facebook:hover { background: #405791; } +/* 人人网按钮样式 */ .btn-sn-renren { background: #197bc8; } +/* 人人网按钮激活、聚焦、悬停样式 */ .btn-sn-renren:active, .btn-sn-renren:focus, .btn-sn-renren:hover { background: #166db1; } +/* 腾讯微博按钮样式 */ .btn-sn-tqq { background: #1f9ed2; } +/* 腾讯微博按钮激活、聚焦、悬停样式 */ .btn-sn-tqq:active, .btn-sn-tqq:focus, .btn-sn-tqq:hover { background: #1c8dbc; } +/* 豆瓣按钮样式 */ .btn-sn-douban { background: #279738; } +/* 豆瓣按钮激活、聚焦、悬停样式 */ .btn-sn-douban:active, .btn-sn-douban:focus, .btn-sn-douban:hover { background: #228330; } +/* 微信按钮样式 */ .btn-sn-weixin { background: #00b500; } +/* 微信按钮激活、聚焦、悬停样式 */ .btn-sn-weixin:active, .btn-sn-weixin:focus, .btn-sn-weixin:hover { background: #009c00; } +/* 虚线按钮样式 */ .btn-sn-dotted { background: #eee; } +/* 虚线按钮激活、聚焦、悬停样式 */ .btn-sn-dotted:active, .btn-sn-dotted:focus, .btn-sn-dotted:hover { background: #e1e1e1; } +/* 网站按钮样式 */ .btn-sn-site { background: #00b500; } +/* 网站按钮激活、聚焦、悬停样式 */ .btn-sn-site:active, .btn-sn-site:focus, .btn-sn-site:hover { background: #009c00; } +/* LinkedIn按钮样式 */ .btn-sn-linkedin { background: #0077b9; } +/* LinkedIn按钮激活、聚焦、悬停样式 */ .btn-sn-linkedin:active, .btn-sn-linkedin:focus, .btn-sn-linkedin:hover { background: #0067a0; } +/* 社交网络按钮通用样式 */ [class*=btn-sn-], [class*=btn-sn-]:active, [class*=btn-sn-]:focus, [class*=btn-sn-]:hover { border: none; color: #fff; } +/* 更多按钮样式 */ .btn-sn-more { padding: 0; } +/* 更多按钮及激活、悬停样式 */ .btn-sn-more, .btn-sn-more:active, .btn-sn-more:hover { box-shadow: none; } +/* 社交网络按钮内的图标样式 */ [class*=btn-sn-] [class*=icon-sn-] { background-color: transparent; } \ No newline at end of file diff --git a/src/collectedstatic/blog/css/style.css b/src/collectedstatic/blog/css/style.css index d43f7f3..13a3040 100644 --- a/src/collectedstatic/blog/css/style.css +++ b/src/collectedstatic/blog/css/style.css @@ -1,3 +1,6 @@ +/* +页面基础样式重置 +*/ 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, 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, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; @@ -6,20 +9,24 @@ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockq vertical-align: baseline; } +/* 页面主体行高 */ body { line-height: 1; } +/* 列表样式 */ ol, ul { list-style: none; } +/* 引用样式 */ blockquote, q { quotes: none; } +/* 引用前后内容 */ blockquote:before, blockquote:after, q:before, @@ -28,11 +35,13 @@ q:after { content: none; } +/* 表格样式 */ table { border-collapse: collapse; border-spacing: 0; } +/* 表格标题和单元格 */ caption, th, td { @@ -40,6 +49,7 @@ td { text-align: left; } +/* 标题清除浮动 */ h1, h2, h3, @@ -49,6 +59,7 @@ h6 { clear: both; } +/* HTML基础样式 */ html { overflow-y: scroll; font-size: 100%; @@ -56,10 +67,12 @@ html { -ms-text-size-adjust: 100%; } +/* 焦点链接轮廓 */ a:focus { outline: thin dotted; } +/* HTML5元素显示 */ article, aside, details, @@ -73,25 +86,30 @@ section { display: block; } +/* 音频、画布、视频元素 */ audio, canvas, video { display: inline-block; } +/* 无控件音频元素 */ audio:not([controls]) { display: none; } +/* 删除线文本颜色 */ del { color: #333; } +/* 插入文本样式 */ ins { background: #fff9c0; text-decoration: none; } +/* 分割线样式 */ hr { background-color: #ccc; border: 0; @@ -100,6 +118,7 @@ hr { margin-bottom: 1.714285714rem; } +/* 上下标样式 */ sub, sup { font-size: 75%; @@ -108,30 +127,35 @@ sup { vertical-align: baseline; } +/* 上标位置 */ sup { top: -0.5em; } +/* 下标位置 */ sub { bottom: -0.25em; } +/* 小号字体 */ small { font-size: smaller; } +/* 图片样式 */ img { border: 0; -ms-interpolation-mode: bicubic; } -/* Clearing floats */ +/* 清除浮动 */ .clear:after, .wrapper:after, .format-status .entry-header:after { clear: both; } +/* 清除浮动辅助 */ .clear:before, .clear:after, .wrapper:before, @@ -142,11 +166,10 @@ img { content: ""; } - -/* =Repeatable patterns +/* =可重复模式 -------------------------------------------------------------- */ -/* Small headers */ +/* 小标题样式 */ .archive-title, .page-title, .widget-title, @@ -160,7 +183,7 @@ img { color: #636363; } -/* Shared Post Format styling */ +/* 共享文章格式样式 */ article.format-quote footer.entry-meta, article.format-link footer.entry-meta, article.format-status footer.entry-meta { @@ -169,7 +192,7 @@ article.format-status footer.entry-meta { line-height: 2.181818182; } -/* Form fields, general styles first */ +/* 表单字段通用样式 */ button, input, select, @@ -181,18 +204,20 @@ textarea { padding: 0.428571429rem; } +/* 按钮和输入框行高 */ button, input { line-height: normal; } +/* 文本域样式 */ textarea { font-size: 100%; overflow: auto; vertical-align: top; } -/* Reset non-text input types */ +/* 重置非文本输入类型 */ input[type="checkbox"], input[type="radio"], input[type="file"], @@ -204,7 +229,7 @@ input[type="color"] { padding: 0; } -/* Buttons */ +/* 按钮样式 */ .menu-toggle, input[type="submit"], input[type="button"], @@ -230,6 +255,7 @@ article.post-password-required input[type=submit], box-shadow: 0 1px 2px rgba(64, 64, 64, 0.1); } +/* 菜单切换按钮、按钮和输入框 */ .menu-toggle, button, input[type="submit"], @@ -238,11 +264,13 @@ input[type="reset"] { cursor: pointer; } +/* 禁用按钮 */ button[disabled], input[disabled] { cursor: default; } +/* 按钮悬停效果 */ .menu-toggle:hover, .menu-toggle:focus, button:hover, @@ -260,6 +288,7 @@ article.post-password-required input[type=submit]:hover { background-image: linear-gradient(to bottom, #f9f9f9, #ebebeb); } +/* 按钮激活状态 */ .menu-toggle:active, .menu-toggle.toggled-on, button:active, @@ -278,6 +307,7 @@ input[type="reset"]:active { border-color: transparent; } +/* 作者评论样式 */ .bypostauthor cite span { color: #fff; background-color: #21759b; @@ -288,28 +318,30 @@ input[type="reset"]:active { padding: 0; } -/* Responsive images */ +/* 响应式图片 */ .entry-content img, .comment-content img, .widget img { - max-width: 100%; /* Fluid images for posts, comments, and widgets */ + max-width: 100%; /* 文章、评论和小工具中的流体图像 */ } +/* 对齐图片 */ img[class*="align"], img[class*="wp-image-"], img[class*="attachment-"] { - height: auto; /* Make sure images with WordPress-added height and width attributes are scaled correctly */ + height: auto; /* 确保带有WordPress添加的高度和宽度属性的图像正确缩放 */ } +/* 全尺寸和大尺寸图片 */ img.size-full, img.size-large, img.header-image, img.wp-post-image { max-width: 100%; - height: auto; /* Make sure images with WordPress-added height and width attributes are scaled correctly */ + height: auto; /* 确保带有WordPress添加的高度和宽度属性的图像正确缩放 */ } -/* Make sure videos and embeds fit their containers */ +/* 确保视频和嵌入内容适应其容器 */ embed, iframe, object, @@ -317,11 +349,12 @@ video { max-width: 100%; } +/* 推特嵌入内容 */ .entry-content .twitter-tweet-rendered { - max-width: 100% !important; /* Override the Twitter embed fixed width */ + max-width: 100% !important; /* 覆盖推特嵌入的固定宽度 */ } -/* Images */ +/* 图片对齐 */ .alignleft { float: left; } @@ -336,22 +369,25 @@ video { margin-right: auto; } +/* WordPress添加的图像样式 */ .entry-content img, .comment-content img, .widget img, img.header-image, .author-avatar img, img.wp-post-image { - /* Add fancy borders to all WordPress-added images but not things like badges and icons and the like */ + /* 为所有WordPress添加的图像添加精美边框,但不包括徽章和图标等 */ border-radius: 3px; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); } +/* 图片说明 */ .wp-caption { - max-width: 100%; /* Keep wide captions from overflowing their container. */ + max-width: 100%; /* 防止宽说明超出其容器 */ padding: 4px; } +/* 图片说明文本 */ .wp-caption .wp-caption-text, .gallery-caption, .entry-caption { @@ -362,6 +398,7 @@ img.wp-post-image { color: #757575; } +/* 表情和RSS小工具图片 */ img.wp-smiley, .rsswidget img { border: 0; @@ -372,6 +409,7 @@ img.wp-smiley, padding: 0; } +/* 相册项目 */ .entry-content dl.gallery-item { margin: 0; } @@ -389,11 +427,13 @@ img.wp-smiley, display: inline; } +/* 单列相册 */ .gallery-columns-1 .gallery-item a { max-width: 100%; width: auto; } +/* 相册图标 */ .gallery .gallery-icon img { height: auto; max-width: 90%; @@ -404,13 +444,14 @@ img.wp-smiley, padding: 3%; } -/* Navigation */ +/* 导航 */ .site-content nav { clear: both; line-height: 2; overflow: hidden; } +/* 上方导航 */ #nav-above { padding: 24px 0; padding: 1.714285714rem 0; @@ -424,6 +465,7 @@ img.wp-smiley, display: block; } +/* 上一页/下一页导航 */ .nav-previous, .previous-image { float: left; @@ -437,18 +479,20 @@ img.wp-smiley, width: 50%; } +/* 单篇文章导航和评论区域 */ .nav-single + .comments-area, #comment-nav-above { margin: 48px 0; margin: 3.428571429rem 0; } -/* Author profiles */ +/* 作者档案 */ .author .archive-header { margin-bottom: 24px; margin-bottom: 1.714285714rem; } +/* 作者信息 */ .author-info { border-top: 1px solid #ededed; margin: 24px 0; @@ -458,6 +502,7 @@ img.wp-smiley, overflow: hidden; } +/* 作者描述段落 */ .author-description p { color: #757575; font-size: 13px; @@ -465,21 +510,22 @@ img.wp-smiley, line-height: 1.846153846; } +/* 作者档案页面作者信息 */ .author.archive .author-info { border-top: 0; margin: 0 0 48px; margin: 0 0 3.428571429rem; } +/* 作者档案页面作者头像 */ .author.archive .author-avatar { margin-top: 0; } - -/* =Basic structure +/* =基本结构 -------------------------------------------------------------- */ -/* Body, links, basics */ +/* 页面主体、链接基础样式 */ html { font-size: 87.5%; } @@ -492,10 +538,12 @@ body { color: #444; } +/* 自定义字体启用 */ body.custom-font-enabled { font-family: "Open Sans", Helvetica, Arial, sans-serif; } +/* 链接样式 */ a { outline: none; color: #21759b; @@ -505,7 +553,7 @@ a:hover { color: #0f3647; } -/* Assistive text */ +/* 辅助文本 */ .assistive-text, .site .screen-reader-text { position: absolute !important; @@ -515,6 +563,7 @@ a:hover { width: 1px; } +/* 主导航辅助文本焦点状态 */ .main-navigation .assistive-text:focus, .site .screen-reader-text:hover, .site .screen-reader-text:active, @@ -532,37 +581,41 @@ a:hover { top: 5px; left: 5px; width: auto; - z-index: 100000; /* Above WP toolbar */ + z-index: 100000; /* 高于WP工具栏 */ } -/* Page structure */ +/* 页面结构 */ .site { padding: 0 24px; padding: 0 1.714285714rem; background-color: #fff; } +/* 站点内容 */ .site-content { margin: 24px 0 0; margin: 1.714285714rem 0 0; } +/* 小工具区域 */ .widget-area { margin: 24px 0 0; margin: 1.714285714rem 0 0; } -/* Header */ +/* 页头 */ .site-header { padding: 24px 0; padding: 1.714285714rem 0; } +/* 站点头部标题 */ .site-header h1, .site-header h2 { text-align: center; } +/* 站点头部标题链接 */ .site-header h1 a, .site-header h2 a { color: #515151; @@ -570,11 +623,13 @@ a:hover { text-decoration: none; } +/* 站点头部标题链接悬停 */ .site-header h1 a:hover, .site-header h2 a:hover { color: #21759b; } +/* 站点头部一级标题 */ .site-header h1 { font-size: 24px; font-size: 1.714285714rem; @@ -583,6 +638,7 @@ a:hover { margin-bottom: 1rem; } +/* 站点头部二级标题 */ .site-header h2 { font-weight: normal; font-size: 13px; @@ -591,18 +647,20 @@ a:hover { color: #757575; } +/* 头部图像 */ .header-image { margin-top: 24px; margin-top: 1.714285714rem; } -/* Navigation Menu */ +/* 导航菜单 */ .main-navigation { margin-top: 24px; margin-top: 1.714285714rem; text-align: center; } +/* 导航菜单项 */ .main-navigation li { margin-top: 24px; margin-top: 1.714285714rem; @@ -611,6 +669,7 @@ a:hover { line-height: 1.42857143; } +/* 导航菜单链接 */ .main-navigation a { color: #5e5e5e; } @@ -620,23 +679,25 @@ a:hover { color: #21759b; } +/* 导航菜单列表 */ .main-navigation ul.nav-menu, .main-navigation div.nav-menu > ul { display: none; } +/* 展开的导航菜单和菜单切换按钮 */ .main-navigation ul.nav-menu.toggled-on, .menu-toggle { display: inline-block; } -/* Banner */ +/* 横幅 */ section[role="banner"] { margin-bottom: 48px; margin-bottom: 3.428571429rem; } -/* Sidebar */ +/* 侧边栏 */ .widget-area .widget { -webkit-hyphens: auto; -moz-hyphens: auto; @@ -646,11 +707,13 @@ section[role="banner"] { word-wrap: break-word; } +/* 侧边栏小工具标题 */ .widget-area .widget h3 { margin-bottom: 24px; margin-bottom: 1.714285714rem; } +/* 侧边栏小工具段落、列表项和文本小工具 */ .widget-area .widget p, .widget-area .widget li, .widget-area .widget .textwidget { @@ -659,11 +722,13 @@ section[role="banner"] { line-height: 1.846153846; } +/* 侧边栏小工具段落 */ .widget-area .widget p { margin-bottom: 24px; margin-bottom: 1.714285714rem; } +/* 侧边栏文本小工具列表 */ .widget-area .textwidget ul, .widget-area .textwidget ol { list-style: disc outside; @@ -671,20 +736,24 @@ section[role="banner"] { margin: 0 0 1.714285714rem; } +/* 侧边栏文本小工具嵌套列表 */ .widget-area .textwidget li > ul, .widget-area .textwidget li > ol { margin-bottom: 0; } +/* 侧边栏文本小工具有序列表 */ .widget-area .textwidget ol { list-style: decimal; } +/* 侧边栏文本小工具列表项 */ .widget-area .textwidget li { margin-left: 36px; margin-left: 2.571428571rem; } +/* 侧边栏小工具链接 */ .widget-area .widget a { color: #757575; } @@ -693,15 +762,17 @@ section[role="banner"] { color: #21759b; } +/* 侧边栏小工具已访问链接 */ .widget-area .widget a:visited { color: #9f9f9f; } +/* 侧边栏搜索框 */ .widget-area #s { - width: 53.66666666666%; /* define a width to avoid dropping a wider submit button */ + width: 53.66666666666%; /* 定义宽度以避免提交按钮换行 */ } -/* Footer */ +/* 页脚 */ footer[role="contentinfo"] { border-top: 1px solid #ededed; clear: both; @@ -718,6 +789,7 @@ footer[role="contentinfo"] { padding: 1.714285714rem 0; } +/* 页脚链接 */ footer[role="contentinfo"] a { color: #686868; } @@ -726,6 +798,7 @@ footer[role="contentinfo"] a:hover { color: #21759b; } +/* 站点信息分隔符 */ .site-info span[role=separator] { padding: 0 0.3em 0 0.6em; } @@ -734,24 +807,27 @@ footer[role="contentinfo"] a:hover { content: '\002f'; } - -/* =Main content and comment content +/* =主要内容和评论内容 -------------------------------------------------------------- */ +/* 文章元数据 */ .entry-meta { clear: both; } +/* 文章头部 */ .entry-header { margin-bottom: 24px; margin-bottom: 1.714285714rem; } +/* 文章特色图像 */ .entry-header img.wp-post-image { margin-bottom: 24px; margin-bottom: 1.714285714rem; } +/* 文章标题 */ .entry-header .entry-title { font-size: 20px; font-size: 1.428571429rem; @@ -759,16 +835,19 @@ footer[role="contentinfo"] a:hover { font-weight: normal; } +/* 文章标题链接 */ .entry-header .entry-title a { text-decoration: none; } +/* 文章格式 */ .entry-header .entry-format { margin-top: 24px; margin-top: 1.714285714rem; font-weight: normal; } +/* 评论链接 */ .entry-header .comments-link { margin-top: 24px; margin-top: 1.714285714rem; @@ -778,6 +857,7 @@ footer[role="contentinfo"] a:hover { color: #757575; } +/* 评论链接和文章元数据链接 */ .comments-link a, .entry-meta a { color: #757575; @@ -788,6 +868,7 @@ footer[role="contentinfo"] a:hover { color: #21759b; } +/* 置顶文章 */ article.sticky .featured-post { border-top: 4px double #ededed; border-bottom: 4px double #ededed; @@ -800,12 +881,14 @@ article.sticky .featured-post { text-align: center; } +/* 文章内容、摘要和注册表单 */ .entry-content, .entry-summary, .mu_register { line-height: 1.714285714; } +/* 文章内容和评论内容标题 */ .entry-content h1, .comment-content h1, .entry-content h2, @@ -823,6 +906,7 @@ article.sticky .featured-post { line-height: 1.714285714; } +/* 一级标题 */ .entry-content h1, .comment-content h1 { font-size: 21px; @@ -830,6 +914,7 @@ article.sticky .featured-post { line-height: 1.5; } +/* 二级标题 */ .entry-content h2, .comment-content h2, .mu_register h2 { @@ -838,6 +923,7 @@ article.sticky .featured-post { line-height: 1.6; } +/* 三级标题 */ .entry-content h3, .comment-content h3 { font-size: 16px; @@ -845,6 +931,7 @@ article.sticky .featured-post { line-height: 1.846153846; } +/* 四级标题 */ .entry-content h4, .comment-content h4 { font-size: 14px; @@ -852,6 +939,7 @@ article.sticky .featured-post { line-height: 1.846153846; } +/* 五级标题 */ .entry-content h5, .comment-content h5 { font-size: 13px; @@ -859,6 +947,7 @@ article.sticky .featured-post { line-height: 1.846153846; } +/* 六级标题 */ .entry-content h6, .comment-content h6 { font-size: 12px; @@ -866,6 +955,7 @@ article.sticky .featured-post { line-height: 1.846153846; } +/* 段落 */ .entry-content p, .entry-summary p, .comment-content p, @@ -875,15 +965,18 @@ article.sticky .featured-post { line-height: 1.714285714; } +/* 已访问链接 */ .entry-content a:visited, .comment-content a:visited { color: #9f9f9f; } +/* 阅读更多链接 */ .entry-content .more-link { white-space: nowrap; } +/* 列表 */ .entry-content ol, .comment-content ol, .entry-content ul, @@ -894,6 +987,7 @@ article.sticky .featured-post { line-height: 1.714285714; } +/* 嵌套列表 */ .entry-content ul ul, .comment-content ul ul, .entry-content ol ol, @@ -905,17 +999,20 @@ article.sticky .featured-post { margin-bottom: 0; } +/* 无序列表 */ .entry-content ul, .comment-content ul, .mu_register ul { list-style: disc outside; } +/* 有序列表 */ .entry-content ol, .comment-content ol { list-style: decimal outside; } +/* 列表项 */ .entry-content li, .comment-content li, .mu_register li { @@ -923,6 +1020,7 @@ article.sticky .featured-post { margin: 0 0 0 2.571428571rem; } +/* 引用 */ .entry-content blockquote, .comment-content blockquote { margin-bottom: 24px; @@ -932,11 +1030,13 @@ article.sticky .featured-post { font-style: italic; } +/* 引用最后一段 */ .entry-content blockquote p:last-child, .comment-content blockquote p:last-child { margin-bottom: 0; } +/* 代码 */ .entry-content code, .comment-content code { font-family: Consolas, Monaco, Lucida Console, monospace; @@ -945,6 +1045,7 @@ article.sticky .featured-post { line-height: 2; } +/* 代码块 */ .entry-content pre, .comment-content pre { border: 1px solid #ededed; @@ -960,11 +1061,13 @@ article.sticky .featured-post { padding: 1.714285714rem; } +/* 代码块中的代码 */ .entry-content pre code, .comment-content pre code { display: block; } +/* 缩写、定义和首字母缩略词 */ .entry-content abbr, .comment-content abbr, .entry-content dfn, @@ -975,6 +1078,7 @@ article.sticky .featured-post { cursor: help; } +/* 地址 */ .entry-content address, .comment-content address { display: block; @@ -983,27 +1087,27 @@ article.sticky .featured-post { margin: 0 0 1.714285714rem; } +/* 左对齐图片和说明 */ img.alignleft, .wp-caption.alignleft { margin: 12px 24px 12px 0; margin: 0.857142857rem 1.714285714rem 0.857142857rem 0; } +/* 右对齐图片和说明 */ img.alignright, .wp-caption.alignright { margin: 12px 0 12px 24px; margin: 0.857142857rem 0 0.857142857rem 1.714285714rem; } +/* 居中图片和说明 */ img.aligncenter, .wp-caption.aligncenter { clear: both; - margin-top: 12px; - margin-top: 0.857142857rem; - margin-bottom: 12px; - margin-bottom: 0.857142857rem; } +/* 嵌入内容 */ .entry-content embed, .entry-content iframe, .entry-content object, @@ -1012,18 +1116,21 @@ img.aligncenter, margin-bottom: 1.714285714rem; } +/* 定义列表 */ .entry-content dl, .comment-content dl { margin: 0 24px; margin: 0 1.714285714rem; } +/* 定义列表标题 */ .entry-content dt, .comment-content dt { font-weight: bold; line-height: 1.714285714; } +/* 定义列表描述 */ .entry-content dd, .comment-content dd { line-height: 1.714285714; @@ -1031,6 +1138,7 @@ img.aligncenter, margin-bottom: 1.714285714rem; } +/* 表格 */ .entry-content table, .comment-content table { border-bottom: 1px solid #ededed; @@ -1043,6 +1151,7 @@ img.aligncenter, width: 100%; } +/* 表格标题 */ .entry-content table caption, .comment-content table caption { font-size: 16px; @@ -1051,12 +1160,14 @@ img.aligncenter, margin: 1.714285714rem 0; } +/* 表格单元格 */ .entry-content td, .comment-content td { border-top: 1px solid #ededed; padding: 6px 10px 6px 0; } +/* 文章 */ .site-content article { border-bottom: 4px double #ededed; margin-bottom: 72px; @@ -1069,11 +1180,13 @@ img.aligncenter, hyphens: auto; } +/* 分页链接 */ .page-links { clear: both; line-height: 1.714285714; } +/* 文章元数据 */ footer.entry-meta { margin-top: 24px; margin-top: 1.714285714rem; @@ -1083,10 +1196,12 @@ footer.entry-meta { color: #757575; } +/* 单个作者的文章元数据 */ .single-author .entry-meta .by-author { display: none; } +/* 注册表单标题 */ .mu_register h2 { color: #757575; font-weight: normal; @@ -1096,6 +1211,7 @@ footer.entry-meta { /* =Archives -------------------------------------------------------------- */ +/* 归档和页面标题 */ .archive-header, .page-header { margin-bottom: 48px; @@ -1105,7 +1221,10 @@ footer.entry-meta { border-bottom: 1px solid #ededed; } +/* 归档元数据 */ .archive-meta { +} + color: #757575; font-size: 12px; font-size: 0.857142857rem; diff --git a/src/collectedstatic/blog/js/blog.js b/src/collectedstatic/blog/js/blog.js index c50dd7d..0f1d47b 100644 --- a/src/collectedstatic/blog/js/blog.js +++ b/src/collectedstatic/blog/js/blog.js @@ -1,40 +1,62 @@ /** + * 博客前端交互功能 * Created by liangliang on 2016/11/20. */ - +/** + * 回复评论功能 + * @param {string} parentid - 父评论ID + */ function do_reply(parentid) { console.log(parentid); + // 设置父评论ID $("#id_parent_comment_id").val(parentid) + // 将评论表单移动到对应评论下 $("#commentform").appendTo($("#div-comment-" + parentid)); + // 隐藏回复标题,显示取消回复按钮 $("#reply-title").hide(); $("#cancel_comment").show(); } +/** + * 取消回复功能 + */ function cancel_reply() { + // 显示回复标题,隐藏取消回复按钮 $("#reply-title").show(); $("#cancel_comment").hide(); + // 清空父评论ID $("#id_parent_comment_id").val('') + // 将评论表单移回原位置 $("#commentform").appendTo($("#respond")); } +// 页面加载进度条控制 NProgress.start(); NProgress.set(0.4); -//Increment +// 增量更新进度条 var interval = setInterval(function () { NProgress.inc(); }, 1000); + +// 文档加载完成后停止进度条 $(document).ready(function () { NProgress.done(); clearInterval(interval); }); - -/** 侧边栏回到顶部 */ +/** 侧边栏回到顶部功能 */ var rocket = $('#rocket'); +// 监听窗口滚动事件,防抖处理 $(window).on('scroll', debounce(slideTopSet, 300)); +/** + * 防抖函数 + * @param {Function} func - 需要防抖的函数 + * @param {number} wait - 等待时间(毫秒) + * @returns {Function} 防抖后的函数 + */ function debounce(func, wait) { var timeout; return function () { @@ -43,45 +65,54 @@ function debounce(func, wait) { }; } +/** + * 设置回到顶部按钮显示状态 + */ function slideTopSet() { var top = $(document).scrollTop(); if (top > 200) { - rocket.addClass('show'); + rocket.addClass('show'); // 滚动超过200px时显示回到顶部按钮 } else { - rocket.removeClass('show'); + rocket.removeClass('show'); // 否则隐藏 } } +// 点击回到顶部按钮事件 $(document).on('click', '#rocket', function (event) { - rocket.addClass('move'); + rocket.addClass('move'); // 添加动画类 + // 页面平滑滚动到顶部 $('body, html').animate({ scrollTop: 0 }, 800); }); + +// 动画结束事件处理 $(document).on('animationEnd', function () { setTimeout(function () { - rocket.removeClass('move'); + rocket.removeClass('move'); // 移除动画类 }, 400); - }); + +// Webkit内核浏览器动画结束事件处理 $(document).on('webkitAnimationEnd', function () { setTimeout(function () { - rocket.removeClass('move'); + rocket.removeClass('move'); // 移除动画类 }, 400); }); - +// 页面加载完成后初始化评论回复功能 window.onload = function () { var replyLinks = document.querySelectorAll(".comment-reply-link"); for (var i = 0; i < replyLinks.length; i++) { replyLinks[i].onclick = function () { var pk = this.getAttribute("data-pk"); - do_reply(pk); + do_reply(pk); // 点击回复链接时调用回复功能 }; } }; +// 国际化语言切换功能(已注释) // $(document).ready(function () { // var form = $('#i18n-form'); // var selector = $('.i18n-select'); diff --git a/src/collectedstatic/blog/js/navigation.js b/src/collectedstatic/blog/js/navigation.js index f7141bf..e229f36 100644 --- a/src/collectedstatic/blog/js/navigation.js +++ b/src/collectedstatic/blog/js/navigation.js @@ -1,6 +1,5 @@ /** - * Handles toggling the navigation menu for small screens and - * accessibility for submenu items. + * 处理小屏幕上的导航菜单切换和子菜单项的可访问性 */ ( function() { var nav = document.getElementById( 'site-navigation' ), button, menu; @@ -14,17 +13,19 @@ return; } - // Hide button if menu is missing or empty. + // 如果菜单不存在或为空则隐藏按钮 if ( ! menu || ! menu.childNodes.length ) { button.style.display = 'none'; return; } + // 按钮点击事件处理 button.onclick = function() { if ( -1 === menu.className.indexOf( 'nav-menu' ) ) { menu.className = 'nav-menu'; } + // 切换菜单展开/收起状态 if ( -1 !== button.className.indexOf( 'toggled-on' ) ) { button.className = button.className.replace( ' toggled-on', '' ); menu.className = menu.className.replace( ' toggled-on', '' ); @@ -35,12 +36,14 @@ }; } )(); -// Better focus for hidden submenu items for accessibility. +// 为隐藏的子菜单项提供更好的焦点支持以提高可访问性 ( function( $ ) { + // 为导航菜单中的链接添加焦点和失焦事件 $( '.main-navigation' ).find( 'a' ).on( 'focus.twentytwelve blur.twentytwelve', function() { $( this ).parents( '.menu-item, .page_item' ).toggleClass( 'focus' ); } ); + // 移动端触摸事件处理 if ( 'ontouchstart' in window ) { $('body').on( 'touchstart.twentytwelve', '.menu-item-has-children > a, .page_item_has_children > a', function( e ) { var el = $( this ).parent( 'li' ); @@ -52,4 +55,4 @@ } } ); } -} )( jQuery ); +} )( jQuery ); \ No newline at end of file diff --git a/src/collectedstatic/mathjax/js/mathjax-config.js b/src/collectedstatic/mathjax/js/mathjax-config.js index 158ba65..5ff80d0 100644 --- a/src/collectedstatic/mathjax/js/mathjax-config.js +++ b/src/collectedstatic/mathjax/js/mathjax-config.js @@ -1,12 +1,17 @@ $(function () { + // 配置MathJax数学公式渲染器 MathJax.Hub.Config({ showProcessingMessages: false, //关闭js加载过程信息 messageStyle: "none", //不显示信息 - extensions: ["tex2jax.js"], jax: ["input/TeX", "output/HTML-CSS"], displayAlign: "left", tex2jax: { + extensions: ["tex2jax.js"], + jax: ["input/TeX", "output/HTML-CSS"], + displayAlign: "left", + tex2jax: { inlineMath: [["$", "$"]], //行内公式选择$ displayMath: [["$$", "$$"]], //段内公式选择$$ skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code', 'a'], //避开某些标签 - }, "HTML-CSS": { + }, + "HTML-CSS": { availableFonts: ["STIX", "TeX"], //可选字体 showMathMenu: false //关闭右击菜单显示 } @@ -14,8 +19,6 @@ $(function () { // 识别范围 => 文章内容、评论内容标签 const contentId = document.getElementById("content"); const commentId = document.getElementById("comments"); + // 将文章内容和评论内容添加到MathJax渲染队列中 MathJax.Hub.Queue(["Typeset", MathJax.Hub, contentId, commentId]); }) - - - diff --git a/src/collectedstatic/mdeditor/css/editormd.css b/src/collectedstatic/mdeditor/css/editormd.css index 261b3d9..b7543ac 100644 --- a/src/collectedstatic/mdeditor/css/editormd.css +++ b/src/collectedstatic/mdeditor/css/editormd.css @@ -1,590 +1,690 @@ /* - * Editor.md - * + * Editor.md v1.5.0 + * 开源在线Markdown编辑器 + * * @file editormd.css * @version v1.5.0 - * @description Open source online markdown editor. + * @description 开源在线Markdown编辑器主样式文件 * @license MIT License * @author Pandao - * {@link https://github.com/pandao/editor.md} + * @link https://github.com/pandao/editor.md * @updateTime 2015-06-09 */ @charset "UTF-8"; + +/* ========================================================================== + 第三方库样式重置和工具类 + ========================================================================== */ + /*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */ + +/* 编辑器主容器样式 */ .editormd { - width: 90%; - height: 640px; - margin: 0 auto; - text-align: left; - overflow: hidden; - position: relative; - margin-bottom: 15px; - border: 1px solid #ddd; + width: 90%; /* 宽度为父元素的90% */ + height: 640px; /* 高度为640像素 */ + margin: 0 auto; /* 水平居中 */ + text-align: left; /* 文本左对齐 */ + overflow: hidden; /* 隐藏溢出内容 */ + position: relative; /* 相对定位 */ + margin-bottom: 15px; /* 下边距15像素 */ + border: 1px solid #ddd; /* 1像素灰色实线边框 */ font-family: "Meiryo UI", "Microsoft YaHei", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, "Monaco", monospace, Tahoma, STXihei, "华文细黑", STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, "宋体", Heiti, "黑体", sans-serif; } + +/* 盒模型设置 - 确保所有子元素使用border-box */ .editormd *, .editormd *:before, .editormd *:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; + -webkit-box-sizing: border-box; /* Webkit浏览器盒模型 */ + -moz-box-sizing: border-box; /* Mozilla浏览器盒模型 */ + box-sizing: border-box; /* 标准盒模型 */ } + +/* 链接样式重置 */ .editormd a { - text-decoration: none; + text-decoration: none; /* 去除链接下划线 */ } + +/* 图片样式重置 */ .editormd img { - border: none; - vertical-align: middle; + border: none; /* 图片无边框 */ + vertical-align: middle; /* 图片垂直居中对齐 */ } + +/* 隐藏文本区域 */ .editormd > textarea, .editormd .editormd-html-textarea, .editormd .editormd-markdown-textarea { - width: 0; - height: 0; - outline: 0; - resize: none; + width: 0; /* 宽度为0 */ + height: 0; /* 高度为0 */ + outline: 0; /* 无轮廓 */ + resize: none; /* 禁止调整大小 */ } + +/* 隐藏HTML和Markdown文本区域 */ .editormd .editormd-html-textarea, .editormd .editormd-markdown-textarea { - display: none; + display: none; /* 隐藏HTML和Markdown文本区域 */ } + +/* 表单元素样式重置 */ .editormd input[type="text"], .editormd input[type="button"], .editormd input[type="submit"], .editormd select, .editormd textarea, .editormd button { - -webkit-appearance: none; - -moz-appearance: none; - -ms-appearance: none; - appearance: none; + -webkit-appearance: none; /* 去除Webkit浏览器默认样式 */ + -moz-appearance: none; /* 去除Mozilla浏览器默认样式 */ + -ms-appearance: none; /* 去除IE浏览器默认样式 */ + appearance: none; /* 去除默认样式 */ } + +/* 滚动条样式自定义 */ .editormd ::-webkit-scrollbar { - height: 10px; - width: 7px; - background: rgba(0, 0, 0, 0.1); + height: 10px; /* 滚动条高度 */ + width: 7px; /* 滚动条宽度 */ + background: rgba(0, 0, 0, 0.1); /* 滚动条背景色 */ } + .editormd ::-webkit-scrollbar:hover { - background: rgba(0, 0, 0, 0.2); + background: rgba(0, 0, 0, 0.2); /* 滚动条悬停背景色 */ } + .editormd ::-webkit-scrollbar-thumb { - background: rgba(0, 0, 0, 0.3); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - -ms-border-radius: 6px; - -o-border-radius: 6px; - border-radius: 6px; + background: rgba(0, 0, 0, 0.3); /* 滚动条滑块背景色 */ + -webkit-border-radius: 6px; /* Webkit浏览器圆角 */ + -moz-border-radius: 6px; /* Mozilla浏览器圆角 */ + -ms-border-radius: 6px; /* IE浏览器圆角 */ + -o-border-radius: 6px; /* Opera浏览器圆角 */ + border-radius: 6px; /* 标准圆角 */ } + .editormd ::-webkit-scrollbar-thumb:hover { - -webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); - /* Webkit browsers */ - -moz-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); - /* Firefox */ - -ms-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); - /* IE9 */ - -o-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); - /* Opera(Old) */ - box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); - /* IE9+, News */ - background-color: rgba(0, 0, 0, 0.4); + -webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); /* Webkit浏览器内阴影 */ + -moz-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); /* Mozilla浏览器内阴影 */ + -ms-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); /* IE浏览器内阴影 */ + -o-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); /* Opera浏览器内阴影 */ + box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); /* 标准内阴影 */ + background-color: rgba(0, 0, 0, 0.4); /* 悬停时的背景色 */ } +/* 禁止用户选择文本 */ .editormd-user-unselect { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; + -webkit-user-select: none; /* Webkit浏览器禁止选择 */ + -moz-user-select: none; /* Mozilla浏览器禁止选择 */ + -ms-user-select: none; /* IE浏览器禁止选择 */ + -o-user-select: none; /* Opera浏览器禁止选择 */ + user-select: none; /* 标准禁止选择 */ } -.editormd-toolbar { - width: 100%; - min-height: 37px; - background: #fff; - display: none; - position: absolute; - top: 0; - left: 0; - z-index: 10; - border-bottom: 1px solid #ddd; -} +/* ========================================================================== + 工具栏样式 + ========================================================================== */ +/* 工具栏主容器 */ +.editormd-toolbar { + width: 100%; /* 宽度100% */ + min-height: 37px; /* 最小高度37像素 */ + background: #fff; /* 白色背景 */ + display: none; /* 默认隐藏 */ + position: absolute; /* 绝对定位 */ + top: 0; /* 距离顶部0像素 */ + left: 0; /* 距离左侧0像素 */ + z-index: 10; /* 层级10 */ + border-bottom: 1px solid #ddd; /* 底部1像素灰色实线边框 */ +} + +/* 工具栏容器 */ .editormd-toolbar-container { - padding: 0 8px; - min-height: 35px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; + padding: 0 8px; /* 内边距 */ + min-height: 35px; /* 最小高度35像素 */ + -webkit-user-select: none; /* Webkit浏览器禁止选择 */ + -moz-user-select: none; /* Mozilla浏览器禁止选择 */ + -ms-user-select: none; /* IE浏览器禁止选择 */ + -o-user-select: none; /* Opera浏览器禁止选择 */ + user-select: none; /* 标准禁止选择 */ } +/* 工具栏菜单 */ .editormd-menu { - margin: 0; - padding: 0; - list-style: none; + margin: 0; /* 外边距为0 */ + padding: 0; /* 内边距为0 */ + list-style: none; /* 无列表样式 */ } + .editormd-menu > li { - margin: 0; - padding: 5px 1px; - display: inline-block; - position: relative; + margin: 0; /* 外边距为0 */ + padding: 5px 1px; /* 内边距 */ + display: inline-block; /* 行内块元素 */ + position: relative; /* 相对定位 */ } + +/* 菜单分隔符 */ .editormd-menu > li.divider { - display: inline-block; - text-indent: -9999px; - margin: 0 5px; - height: 65%; - border-right: 1px solid #ddd; + display: inline-block; /* 行内块元素 */ + text-indent: -9999px; /* 缩进隐藏分隔符文字 */ + margin: 0 5px; /* 外边距 */ + height: 65%; /* 高度为父元素的65% */ + border-right: 1px solid #ddd; /* 右侧1像素灰色实线边框 */ } + +/* 菜单项链接 */ .editormd-menu > li > a { - outline: 0; - color: #666; - display: inline-block; - min-width: 24px; - font-size: 16px; - text-decoration: none; - text-align: center; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - -ms-border-radius: 2px; - -o-border-radius: 2px; - border-radius: 2px; - border: 1px solid #fff; - -webkit-transition: all 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: all 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: all 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + outline: 0; /* 无轮廓 */ + color: #666; /* 文字颜色 */ + display: inline-block; /* 行内块元素 */ + min-width: 24px; /* 最小宽度24像素 */ + font-size: 16px; /* 字体大小16像素 */ + text-decoration: none; /* 无文本装饰 */ + text-align: center; /* 文本居中 */ + -webkit-border-radius: 2px; /* Webkit浏览器圆角 */ + -moz-border-radius: 2px; /* Mozilla浏览器圆角 */ + -ms-border-radius: 2px; /* IE浏览器圆角 */ + -o-border-radius: 2px; /* Opera浏览器圆角 */ + border-radius: 2px; /* 标准圆角 */ + border: 1px solid #fff; /* 1像素白色实线边框 */ + -webkit-transition: all 300ms ease-out; /* Webkit浏览器过渡效果 */ + -moz-transition: all 300ms ease-out; /* Mozilla浏览器过渡效果 */ + transition: all 300ms ease-out; /* 标准过渡效果 */ } + .editormd-menu > li > a:hover, .editormd-menu > li > a.active { - border: 1px solid #ddd; - background: #eee; + border: 1px solid #ddd; /* 1像素灰色实线边框 */ + background: #eee; /* 背景色 */ } + .editormd-menu > li > a > .fa { - text-align: center; - display: block; - padding: 5px; + text-align: center; /* 文本居中 */ + display: block; /* 块级元素 */ + padding: 5px; /* 内边距 */ } + .editormd-menu > li > a > .editormd-bold { - padding: 5px 2px; - display: inline-block; - font-weight: bold; + padding: 5px 2px; /* 内边距 */ + display: inline-block; /* 行内块元素 */ + font-weight: bold; /* 粗体 */ } + +/* 下拉菜单显示 */ .editormd-menu > li:hover .editormd-dropdown-menu { - display: block; + display: block; /* 悬停时显示下拉菜单 */ } + .editormd-menu > li + li > a { - margin-left: 3px; + margin-left: 3px; /* 左外边距3像素 */ } +/* 下拉菜单样式 */ .editormd-dropdown-menu { - display: none; - background: #fff; - border: 1px solid #ddd; - width: 148px; - list-style: none; - position: absolute; - top: 33px; - left: 0; - z-index: 100; - -webkit-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); - /* Webkit browsers */ - -moz-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); - /* Firefox */ - -ms-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); - /* IE9 */ - -o-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); - /* Opera(Old) */ - box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); - /* IE9+, News */ + display: none; /* 默认隐藏 */ + background: #fff; /* 白色背景 */ + border: 1px solid #ddd; /* 1像素灰色实线边框 */ + width: 148px; /* 宽度148像素 */ + list-style: none; /* 无列表样式 */ + position: absolute; /* 绝对定位 */ + top: 33px; /* 距离顶部33像素 */ + left: 0; /* 距离左侧0像素 */ + z-index: 100; /* 层级100 */ + -webkit-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); /* Webkit浏览器阴影 */ + -moz-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); /* Mozilla浏览器阴影 */ + -ms-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); /* IE浏览器阴影 */ + -o-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); /* Opera浏览器阴影 */ + box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); /* 标准阴影 */ } + .editormd-dropdown-menu:before, .editormd-dropdown-menu:after { - width: 0; - height: 0; - display: block; - content: ""; - position: absolute; - top: -11px; - left: 8px; - border: 5px solid transparent; + width: 0; /* 宽度为0 */ + height: 0; /* 高度为0 */ + display: block; /* 块级元素 */ + content: ""; /* 空内容 */ + position: absolute; /* 绝对定位 */ + top: -11px; /* 距离顶部-11像素 */ + left: 8px; /* 距离左侧8像素 */ + border: 5px solid transparent; /* 5像素透明实线边框 */ } + .editormd-dropdown-menu:before { - border-bottom-color: #ccc; + border-bottom-color: #ccc; /* 底部边框颜色 */ } + .editormd-dropdown-menu:after { - border-bottom-color: #ffffff; - top: -10px; + border-bottom-color: #ffffff; /* 底部边框颜色为白色 */ + top: -10px; /* 距离顶部-10像素 */ } + .editormd-dropdown-menu > li > a { - color: #666; - display: block; - text-decoration: none; - padding: 8px 10px; + color: #666; /* 文字颜色 */ + display: block; /* 块级元素 */ + text-decoration: none; /* 无文本装饰 */ + padding: 8px 10px; /* 内边距 */ } + .editormd-dropdown-menu > li > a:hover { - background: #f6f6f6; - -webkit-transition: all 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: all 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: all 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + background: #f6f6f6; /* 背景色 */ + -webkit-transition: all 300ms ease-out; /* Webkit浏览器过渡效果 */ + -moz-transition: all 300ms ease-out; /* Mozilla浏览器过渡效果 */ + transition: all 300ms ease-out; /* 标准过渡效果 */ } + .editormd-dropdown-menu > li + li { - border-top: 1px solid #ddd; + border-top: 1px solid #ddd; /* 顶部1像素灰色实线边框 */ } -.editormd-container { - margin: 0; - width: 100%; - height: 100%; - overflow: hidden; - padding: 35px 0 0; - position: relative; - background: #fff; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} +/* ========================================================================== + 编辑器容器样式 + ========================================================================== */ +/* 编辑器内容容器 */ +.editormd-container { + margin: 0; /* 外边距为0 */ + width: 100%; /* 宽度100% */ + height: 100%; /* 高度100% */ + overflow: hidden; /* 隐藏溢出内容 */ + padding: 35px 0 0; /* 内边距 */ + position: relative; /* 相对定位 */ + background: #fff; /* 白色背景 */ + -webkit-box-sizing: border-box; /* Webkit浏览器盒模型 */ + -moz-box-sizing: border-box; /* Mozilla浏览器盒模型 */ + box-sizing: border-box; /* 标准盒模型 */ +} + +/* ========================================================================== + 对话框样式 + ========================================================================== */ + +/* 对话框主容器 */ .editormd-dialog { - color: #666; - position: fixed; - z-index: 99999; - display: none; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - /* Webkit browsers */ - -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - /* Firefox */ - -ms-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - /* IE9 */ - -o-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - /* Opera(Old) */ - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - /* IE9+, News */ - background: #fff; - font-size: 14px; -} - + color: #666; /* 文字颜色 */ + position: fixed; /* 固定定位 */ + z-index: 99999; /* 层级99999 */ + display: none; /* 默认隐藏 */ + -webkit-border-radius: 3px; /* Webkit浏览器圆角 */ + -moz-border-radius: 3px; /* Mozilla浏览器圆角 */ + -ms-border-radius: 3px; /* IE浏览器圆角 */ + -o-border-radius: 3px; /* Opera浏览器圆角 */ + border-radius: 3px; /* 标准圆角 */ + -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* Webkit浏览器阴影 */ + -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* Mozilla浏览器阴影 */ + -ms-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* IE浏览器阴影 */ + -o-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* Opera浏览器阴影 */ + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* 标准阴影 */ + background: #fff; /* 白色背景 */ + font-size: 14px; /* 字体大小14像素 */ +} + +/* 对话框内容容器 */ .editormd-dialog-container { - position: relative; - padding: 20px; - line-height: 1.4; + position: relative; /* 相对定位 */ + padding: 20px; /* 内边距20像素 */ + line-height: 1.4; /* 行高1.4 */ } + .editormd-dialog-container h1 { - font-size: 24px; - margin-bottom: 10px; + font-size: 24px; /* 字体大小24像素 */ + margin-bottom: 10px; /* 下外边距10像素 */ } + .editormd-dialog-container h1 .fa { - color: #2C7EEA; - padding-right: 5px; + color: #2C7EEA; /* 文字颜色 */ + padding-right: 5px; /* 右内边距5像素 */ } + .editormd-dialog-container h1 small { - padding-left: 5px; - font-weight: normal; - font-size: 12px; - color: #999; + padding-left: 5px; /* 左内边距5像素 */ + font-weight: normal; /* 正常字体粗细 */ + font-size: 12px; /* 字体大小12像素 */ + color: #999; /* 文字颜色 */ } + .editormd-dialog-container select { - color: #999; - padding: 3px 8px; - border: 1px solid #ddd; + color: #999; /* 文字颜色 */ + padding: 3px 8px; /* 内边距 */ + border: 1px solid #ddd; /* 1像素灰色实线边框 */ } +/* 对话框关闭按钮 */ .editormd-dialog-close { - position: absolute; - top: 12px; - right: 15px; - font-size: 18px; - color: #ccc; - -webkit-transition: color 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: color 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: color 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + position: absolute; /* 绝对定位 */ + top: 12px; /* 距离顶部12像素 */ + right: 15px; /* 距离右侧15像素 */ + font-size: 18px; /* 字体大小18像素 */ + color: #ccc; /* 文字颜色 */ + -webkit-transition: color 300ms ease-out; /* Webkit浏览器过渡效果 */ + -moz-transition: color 300ms ease-out; /* Mozilla浏览器过渡效果 */ + transition: color 300ms ease-out; /* 标准过渡效果 */ } + .editormd-dialog-close:hover { - color: #999; + color: #999; /* 悬停时文字颜色 */ } +/* 对话框头部 */ .editormd-dialog-header { - padding: 11px 20px; - border-bottom: 1px solid #eee; - -webkit-transition: background 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: background 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: background 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + padding: 11px 20px; /* 内边距 */ + border-bottom: 1px solid #eee; /* 底部1像素浅灰色实线边框 */ + -webkit-transition: background 300ms ease-out; /* Webkit浏览器过渡效果 */ + -moz-transition: background 300ms ease-out; /* Mozilla浏览器过渡效果 */ + transition: background 300ms ease-out; /* 标准过渡效果 */ } + .editormd-dialog-header:hover { - background: #f6f6f6; + background: #f6f6f6; /* 悬停时背景色 */ } +/* 对话框标题 */ .editormd-dialog-title { - font-size: 14px; + font-size: 14px; /* 字体大小14像素 */ } +/* 对话框底部 */ .editormd-dialog-footer { - padding: 10px 0 0 0; - text-align: right; + padding: 10px 0 0 0; /* 内边距 */ + text-align: right; /* 文本右对齐 */ } +/* 信息对话框 */ .editormd-dialog-info { - width: 420px; + width: 420px; /* 宽度420像素 */ } + .editormd-dialog-info h1 { - font-weight: normal; + font-weight: normal; /* 正常字体粗细 */ } + .editormd-dialog-info .editormd-dialog-container { - padding: 20px 25px 25px; + padding: 20px 25px 25px; /* 内边距 */ } + .editormd-dialog-info .editormd-dialog-close { - top: 10px; - right: 10px; + top: 10px; /* 距离顶部10像素 */ + right: 10px; /* 距离右侧10像素 */ } + .editormd-dialog-info p > a, .editormd-dialog-info .hover-link:hover { - color: #2196F3; + color: #2196F3; /* 文字颜色 */ } + .editormd-dialog-info .hover-link { - color: #666; + color: #666; /* 文字颜色 */ } + .editormd-dialog-info a .fa-external-link { - display: none; + display: none; /* 默认隐藏外部链接图标 */ } + .editormd-dialog-info a:hover { - color: #2196F3; + color: #2196F3; /* 悬停时文字颜色 */ } + .editormd-dialog-info a:hover .fa-external-link { - display: inline-block; + display: inline-block; /* 悬停时显示外部链接图标 */ } +/* ========================================================================== + 遮罩层样式 + ========================================================================== */ + +/* 遮罩层基础样式 */ .editormd-mask, .editormd-container-mask, .editormd-dialog-mask { - display: none; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; + display: none; /* 默认隐藏 */ + width: 100%; /* 宽度100% */ + height: 100%; /* 高度100% */ + position: absolute; /* 绝对定位 */ + top: 0; /* 距离顶部0像素 */ + left: 0; /* 距离左侧0像素 */ } +/* 遮罩层背景 */ .editormd-mask, .editormd-dialog-mask-bg { - background: #fff; - opacity: 0.5; - filter: alpha(opacity=50); + background: #fff; /* 白色背景 */ + opacity: 0.5; /* 透明度0.5 */ + filter: alpha(opacity=50); /* IE透明度 */ } +/* 全局遮罩层 */ .editormd-mask { - position: fixed; - background: #000; - opacity: 0.2; - /* W3C */ - filter: alpha(opacity=20); - /* IE */ - z-index: 99998; + position: fixed; /* 固定定位 */ + background: #000; /* 黑色背景 */ + opacity: 0.2; /* 透明度0.2 */ + z-index: 99998; /* 层级99998 */ } +/* 容器遮罩层和对话框遮罩内容 */ .editormd-container-mask, .editormd-dialog-mask-con { - background: url(../images/loading.gif) no-repeat center center; - -webkit-background-size: 32px 32px; - /* Chrome, iOS, Safari */ - -moz-background-size: 32px 32px; - /* Firefox 3.6~4.0 */ - -o-background-size: 32px 32px; - /* Opera 9.5 */ - background-size: 32px 32px; - /* IE9+, New */ + background: url(../images/loading.gif) no-repeat center center; /* 加载动画背景图 */ + -webkit-background-size: 32px 32px; /* Webkit浏览器背景图大小 */ + -moz-background-size: 32px 32px; /* Mozilla浏览器背景图大小 */ + -o-background-size: 32px 32px; /* Opera浏览器背景图大小 */ + background-size: 32px 32px; /* 标准背景图大小 */ } +/* 容器遮罩层 */ .editormd-container-mask { - z-index: 20; - display: block; - background-color: #fff; + z-index: 20; /* 层级20 */ + display: block; /* 显示 */ + background-color: #fff; /* 白色背景 */ } +/* 高分辨率屏幕适配 */ @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) { .editormd-container-mask, .editormd-dialog-mask-con { - background-image: url(../images/loading@2x.gif); + background-image: url(../images/loading@2x.gif); /* 高分辨率加载动画背景图 */ } } + @media only screen and (-webkit-min-device-pixel-ratio: 3), only screen and (min-device-pixel-ratio: 3) { .editormd-container-mask, .editormd-dialog-mask-con { - background-image: url(../images/loading@3x.gif); + background-image: url(../images/loading@3x.gif); /* 更高分辨率加载动画背景图 */ } } + +/* ========================================================================== + 代码块对话框样式 + ========================================================================== */ + +/* 代码块对话框文本区域 */ .editormd-code-block-dialog textarea, .editormd-preformatted-text-dialog textarea { - width: 100%; - height: 400px; - margin-bottom: 6px; - overflow: auto; - border: 1px solid #eee; - background: #fff; - padding: 15px; - resize: none; + width: 100%; /* 宽度100% */ + height: 400px; /* 高度400像素 */ + margin-bottom: 6px; /* 下外边距6像素 */ + overflow: auto; /* 自动滚动条 */ + border: 1px solid #eee; /* 1像素浅灰色实线边框 */ + background: #fff; /* 白色背景 */ + padding: 15px; /* 内边距15像素 */ + resize: none; /* 禁止调整大小 */ } +/* 代码工具栏 */ .editormd-code-toolbar { - color: #999; - font-size: 14px; - margin: -5px 0 10px; + color: #999; /* 文字颜色 */ + font-size: 14px; /* 字体大小14像素 */ + margin: -5px 0 10px; /* 外边距 */ } +/* ========================================================================== + 网格表格样式 + ========================================================================== */ + +/* 网格表格 */ .editormd-grid-table { - width: 99%; - display: table; - border: 1px solid #ddd; - border-collapse: collapse; + width: 99%; /* 宽度99% */ + display: table; /* 表格显示 */ + border: 1px solid #ddd; /* 1像素灰色实线边框 */ + border-collapse: collapse; /* 边框合并 */ } .editormd-grid-table-row { - width: 100%; - display: table-row; + width: 100%; /* 宽度100% */ + display: table-row; /* 表格行显示 */ } + .editormd-grid-table-row a { - font-size: 1.4em; - width: 5%; - height: 36px; - color: #999; - text-align: center; - display: table-cell; - vertical-align: middle; - border: 1px solid #ddd; - text-decoration: none; - -webkit-transition: background-color 300ms ease-out, color 100ms ease-in; - /* Safari, Chrome */ - -moz-transition: background-color 300ms ease-out, color 100ms ease-in; - /* Firefox 4.0~16.0 */ - transition: background-color 300ms ease-out, color 100ms ease-in; - /* IE >9, FF >15, Opera >12.0 */ + font-size: 1.4em; /* 字体大小1.4em */ + width: 5%; /* 宽度5% */ + height: 36px; /* 高度36像素 */ + color: #999; /* 文字颜色 */ + text-align: center; /* 文本居中 */ + display: table-cell; /* 表格单元格显示 */ + vertical-align: middle; /* 垂直居中 */ + border: 1px solid #ddd; /* 1像素灰色实线边框 */ + text-decoration: none; /* 无文本装饰 */ + -webkit-transition: background-color 300ms ease-out, color 100ms ease-in; /* Webkit浏览器过渡效果 */ + -moz-transition: background-color 300ms ease-out, color 100ms ease-in; /* Mozilla浏览器过渡效果 */ + transition: background-color 300ms ease-out, color 100ms ease-in; /* 标准过渡效果 */ } + .editormd-grid-table-row a.selected { - color: #666; - background-color: #eee; + color: #666; /* 文字颜色 */ + background-color: #eee; /* 背景色 */ } + .editormd-grid-table-row a:hover { - color: #777; - background-color: #f6f6f6; + color: #777; /* 悬停时文字颜色 */ + background-color: #f6f6f6; /* 悬停时背景色 */ } +/* ========================================================================== + 标签页样式 + ========================================================================== */ + +/* 标签页头部 */ .editormd-tab-head { - list-style: none; - border-bottom: 1px solid #ddd; + list-style: none; /* 无列表样式 */ + border-bottom: 1px solid #ddd; /* 底部1像素灰色实线边框 */ } + .editormd-tab-head li { - display: inline-block; + display: inline-block; /* 行内块元素 */ } + .editormd-tab-head li a { - color: #999; - display: block; - padding: 6px 12px 5px; - text-align: center; - text-decoration: none; - margin-bottom: -1px; - border: 1px solid #ddd; - -webkit-border-top-left-radius: 3px; - -moz-border-top-left-radius: 3px; - -ms-border-top-left-radius: 3px; - -o-border-top-left-radius: 3px; - border-top-left-radius: 3px; - -webkit-border-top-right-radius: 3px; - -moz-border-top-right-radius: 3px; - -ms-border-top-right-radius: 3px; - -o-border-top-right-radius: 3px; - border-top-right-radius: 3px; - background: #f6f6f6; - -webkit-transition: all 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: all 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: all 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + color: #999; /* 文字颜色 */ + display: block; /* 块级元素 */ + padding: 6px 12px 5px; /* 内边距 */ + text-align: center; /* 文本居中 */ + text-decoration: none; /* 无文本装饰 */ + margin-bottom: -1px; /* 下外边距-1像素 */ + border: 1px solid #ddd; /* 1像素灰色实线边框 */ + -webkit-border-top-left-radius: 3px; /* Webkit浏览器左上圆角 */ + -moz-border-top-left-radius: 3px; /* Mozilla浏览器左上圆角 */ + -ms-border-top-left-radius: 3px; /* IE浏览器左上圆角 */ + -o-border-top-left-radius: 3px; /* Opera浏览器左上圆角 */ + border-top-left-radius: 3px; /* 标准左上圆角 */ + -webkit-border-top-right-radius: 3px; /* Webkit浏览器右上圆角 */ + -moz-border-top-right-radius: 3px; /* Mozilla浏览器右上圆角 */ + -ms-border-top-right-radius: 3px; /* IE浏览器右上圆角 */ + -o-border-top-right-radius: 3px; /* Opera浏览器右上圆角 */ + border-top-right-radius: 3px; /* 标准右上圆角 */ + background: #f6f6f6; /* 背景色 */ + -webkit-transition: all 300ms ease-out; /* Webkit浏览器过渡效果 */ + -moz-transition: all 300ms ease-out; /* Mozilla浏览器过渡效果 */ + transition: all 300ms ease-out; /* 标准过渡效果 */ } + .editormd-tab-head li a:hover { - color: #666; - background: #eee; + color: #666; /* 悬停时文字颜色 */ + background: #eee; /* 悬停时背景色 */ } + .editormd-tab-head li.active a { - color: #666; - background: #fff; - border-bottom-color: #fff; + color: #666; /* 文字颜色 */ + background: #fff; /* 背景色 */ + border-bottom-color: #fff; /* 底部边框颜色 */ } + .editormd-tab-head li + li { - margin-left: 3px; + margin-left: 3px; /* 左外边距3像素 */ } +/* 标签页内容 */ .editormd-tab-box { - padding: 20px 0; + padding: 20px 0; /* 内边距 */ } +/* ========================================================================== + 表单样式 + ========================================================================== */ + +/* 表单基础样式 */ .editormd-form { - color: #666; + color: #666; /* 文字颜色 */ } + .editormd-form label { - float: left; - display: block; - width: 75px; - text-align: left; - padding: 7px 0 15px 5px; - margin: 0 0 2px; - font-weight: normal; + float: left; /* 左浮动 */ + display: block; /* 块级元素 */ + width: 75px; /* 宽度75像素 */ + text-align: left; /* 文本左对齐 */ + padding: 7px 0 15px 5px; /* 内边距 */ + margin: 0 0 2px; /* 外边距 */ + font-weight: normal; /* 正常字体粗细 */ } + .editormd-form br { - clear: both; + clear: both; /* 清除浮动 */ } + .editormd-form iframe { - display: none; + display: none; /* 隐藏iframe */ } + .editormd-form input:focus { - outline: 0; + outline: 0; /* 聚焦时无轮廓 */ } + .editormd-form input[type="text"], .editormd-form input[type="number"] { - color: #999; - padding: 8px; - border: 1px solid #ddd; + color: #999; /* 文字颜色 */ + padding: 8px; /* 内边距 */ + border: 1px solid #ddd; /* 1像素灰色实线边框 */ } + .editormd-form input[type="number"] { - width: 40px; - display: inline-block; - padding: 6px 8px; + width: 40px; /* 宽度40像素 */ + display: inline-block; /* 行内块元素 */ + padding: 6px 8px; /* 内边距 */ } + .editormd-form input[type="text"] { - display: inline-block; - width: 264px; + display: inline-block; /* 行内块元素 */ + width: 264px; /* 宽度264像素 */ } + +/* FontAwesome按钮组 */ .editormd-form .fa-btns { - display: inline-block; + display: inline-block; /* 行内块元素 */ } + .editormd-form .fa-btns a { - color: #999; - padding: 7px 10px 0 0; - display: inline-block; - text-decoration: none; - text-align: center; + color: #999; /* 文字颜色 */ + padding: 7px 10px 0 0; /* 内边距 */ + display: inline-block; /* 行内块元素 */ + text-decoration: none; /* 无文本装饰 */ + text-align: center; /* 文本居中 */ } + .editormd-form .fa-btns .fa { - font-size: 1.3em; + font-size: 1.3em; /* 字体大小1.3em */ } + .editormd-form .fa-btns label { - float: none; - display: inline-block; - width: auto; - text-align: left; - padding: 0 0 0 5px; - cursor: pointer; + float: none; /* 无浮动 */ + display: inline-block; /* 行内块元素 */ + width: auto; /* 自动宽度 */ + text-align: left; /* 文本左对齐 */ + padding: 0 0 0 5px; /* 内边距 */ + cursor: pointer; /* 鼠标指针样式 */ } +/* ========================================================================== + 表单按钮样式 + ========================================================================== */ + +/* 表单按钮基础样式 */ .editormd-form input[type="submit"], .editormd-form .editormd-btn, .editormd-form button, .editormd-dialog-container input[type="submit"], .editormd-dialog-container .editormd-btn, @@ -592,24 +692,22 @@ .editormd-dialog-footer input[type="submit"], .editormd-dialog-footer .editormd-btn, .editormd-dialog-footer button { - color: #666; - min-width: 75px; - cursor: pointer; - background: #fff; - padding: 7px 10px; - border: 1px solid #ddd; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; - -webkit-transition: background 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: background 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: background 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + color: #666; /* 文字颜色 */ + min-width: 75px; /* 最小宽度75像素 */ + cursor: pointer; /* 鼠标指针样式 */ + background: #fff; /* 白色背景 */ + padding: 7px 10px; /* 内边距 */ + border: 1px solid #ddd; /* 1像素灰色实线边框 */ + -webkit-border-radius: 3px; /* Webkit浏览器圆角 */ + -moz-border-radius: 3px; /* Mozilla浏览器圆角 */ + -ms-border-radius: 3px; /* IE浏览器圆角 */ + -o-border-radius: 3px; /* Opera浏览器圆角 */ + border-radius: 3px; /* 标准圆角 */ + -webkit-transition: background 300ms ease-out; /* Webkit浏览器过渡效果 */ + -moz-transition: background 300ms ease-out; /* Mozilla浏览器过渡效果 */ + transition: background 300ms ease-out; /* 标准过渡效果 */ } + .editormd-form input[type="submit"]:hover, .editormd-form .editormd-btn:hover, .editormd-form button:hover, .editormd-dialog-container input[type="submit"]:hover, .editormd-dialog-container .editormd-btn:hover, @@ -617,114 +715,141 @@ .editormd-dialog-footer input[type="submit"]:hover, .editormd-dialog-footer .editormd-btn:hover, .editormd-dialog-footer button:hover { - background: #eee; + background: #eee; /* 悬停时背景色 */ } + .editormd-form .editormd-btn, .editormd-dialog-container .editormd-btn, .editormd-dialog-footer .editormd-btn { - padding: 5px 8px 4px\0; + padding: 5px 8px 4px\0; /* 内边距(IE hack) */ } + .editormd-form .editormd-btn + .editormd-btn, .editormd-dialog-container .editormd-btn + .editormd-btn, .editormd-dialog-footer .editormd-btn + .editormd-btn { - margin-left: 8px; + margin-left: 8px; /* 左外边距8像素 */ } +/* ========================================================================== + 文件输入框样式 + ========================================================================== */ + +/* 文件输入框容器 */ .editormd-file-input { - width: 75px; - height: 32px; - margin-left: 8px; - position: relative; - display: inline-block; + width: 75px; /* 宽度75像素 */ + height: 32px; /* 高度32像素 */ + margin-left: 8px; /* 左外边距8像素 */ + position: relative; /* 相对定位 */ + display: inline-block; /* 行内块元素 */ } + .editormd-file-input input[type="file"] { - width: 75px; - height: 32px; - opacity: 0; - cursor: pointer; - background: #000; - display: inline-block; - position: absolute; - top: 0; - right: 0; + width: 75px; /* 宽度75像素 */ + height: 32px; /* 高度32像素 */ + opacity: 0; /* 透明度0 */ + cursor: pointer; /* 鼠标指针样式 */ + background: #000; /* 黑色背景 */ + display: inline-block; /* 行内块元素 */ + position: absolute; /* 绝对定位 */ + top: 0; /* 距离顶部0像素 */ + right: 0; /* 距离右侧0像素 */ } + .editormd-file-input input[type="file"]::-webkit-file-upload-button { - visibility: hidden; + visibility: hidden; /* 隐藏Webkit浏览器文件上传按钮 */ } + .editormd-file-input:hover input[type="submit"] { - background: #eee; + background: #eee; /* 悬停时背景色 */ } +/* ========================================================================== + CodeMirror编辑器和预览区域样式 + ========================================================================== */ + +/* CodeMirror编辑器和预览区域基础样式 */ .editormd .CodeMirror, .editormd-preview { - display: inline-block; - width: 50%; - height: 100%; - vertical-align: top; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - margin: 0; + display: inline-block; /* 行内块元素 */ + width: 50%; /* 宽度50% */ + height: 100%; /* 高度100% */ + vertical-align: top; /* 垂直顶部对齐 */ + -webkit-box-sizing: border-box; /* Webkit浏览器盒模型 */ + -moz-box-sizing: border-box; /* Mozilla浏览器盒模型 */ + box-sizing: border-box; /* 标准盒模型 */ + margin: 0; /* 外边距为0 */ } +/* 预览区域 */ .editormd-preview { - position: absolute; - top: 35px; - right: 0; - right: -1px\0; - overflow: auto; - line-height: 1.6; - display: none; - background: #fff; + position: absolute; /* 绝对定位 */ + top: 35px; /* 距离顶部35像素 */ + right: 0; /* 距离右侧0像素 */ + overflow: auto; /* 自动滚动条 */ + line-height: 1.6; /* 行高1.6 */ + display: none; /* 默认隐藏 */ + background: #fff; /* 白色背景 */ } +/* CodeMirror编辑器 */ .editormd .CodeMirror { - z-index: 10; - float: left; - border-right: 1px solid #ddd; - font-size: 14px; + z-index: 10; /* 层级10 */ + float: left; /* 左浮动 */ + border-right: 1px solid #ddd; /* 右侧1像素灰色实线边框 */ + font-size: 14px; /* 字体大小14像素 */ font-family: "YaHei Consolas Hybrid", Consolas, "微软雅黑", "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, "Monaco", courier, monospace; - line-height: 1.6; - margin-top: 35px; + line-height: 1.6; /* 行高1.6 */ + margin-top: 35px; /* 上外边距35像素 */ } + .editormd .CodeMirror pre { - font-size: 14px; - padding: 0 12px; + font-size: 14px; /* 字体大小14像素 */ + padding: 0 12px; /* 内边距 */ } + .editormd .CodeMirror-linenumbers { - padding: 0 5px; + padding: 0 5px; /* 内边距 */ } + .editormd .CodeMirror-selected { - background: #70B7FF; + background: #70B7FF; /* 选中文本背景色 */ } + .editormd .CodeMirror-focused .CodeMirror-selected { - background: #70B7FF; + background: #70B7FF; /* 聚焦时选中文本背景色 */ } + .editormd .CodeMirror, .editormd .CodeMirror-scroll, .editormd .editormd-preview { - -webkit-overflow-scrolling: touch; + -webkit-overflow-scrolling: touch; /* Webkit浏览器触摸滚动 */ } + .editormd .styled-background { - background-color: #ff7; + background-color: #ff7; /* 背景色 */ } + .editormd .CodeMirror-focused .cm-matchhighlight { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==); - background-position: bottom; - background-repeat: repeat-x; + background-position: bottom; /* 背景图片位置 */ + background-repeat: repeat-x; /* 背景图片重复方式 */ } + .editormd .CodeMirror-empty.CodeMirror-focused { - outline: none; + outline: none; /* 聚焦时无轮廓 */ } + .editormd .CodeMirror pre.CodeMirror-placeholder { - color: #999; + color: #999; /* 占位符文字颜色 */ } + .editormd .cm-trailingspace { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg==); - background-position: bottom left; - background-repeat: repeat-x; + background-position: bottom left; /* 背景图片位置 */ + background-repeat: repeat-x; /* 背景图片重复方式 */ } + .editormd .cm-tab { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=); - background-position: right; - background-repeat: no-repeat; + background-position: right; /* 背景图片位置 */ + background-repeat: no-repeat; /* 背景图片不重复 */ } /*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */ @@ -734,6 +859,7 @@ */ /* FONT PATH * -------------------------- */ +/* FontAwesome字体图标 */ @font-face { font-family: 'FontAwesome'; src: url("../fonts/fontawesome-webfont.eot?v=4.3.0"); @@ -741,6 +867,7 @@ font-weight: normal; font-style: normal; } +/* FontAwesome图标基础样式 */ .fa { display: inline-block; font: normal normal normal 14px/1 FontAwesome; @@ -925,127 +1052,156 @@ color: #ffffff; } -/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen - readers do not read off random characters that represent icons */ +/* Font Awesome使用Unicode私用区(PUA)确保屏幕阅读器不会读出代表图标的随机字符 */ +/* 玻璃杯图标 */ .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"; diff --git a/src/collectedstatic/mdeditor/css/editormd.logo.css b/src/collectedstatic/mdeditor/css/editormd.logo.css index 08d9c5b..f2fc733 100644 --- a/src/collectedstatic/mdeditor/css/editormd.logo.css +++ b/src/collectedstatic/mdeditor/css/editormd.logo.css @@ -11,6 +11,8 @@ */ /*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */ +/* 定义editormd-logo字体 */ +/* Define editormd-logo font */ @font-face { font-family: 'editormd-logo'; src: url("../fonts/editormd-logo.eot?-5y8q6h"); @@ -18,6 +20,9 @@ font-weight: normal; font-style: normal; } + +/* editormd-logo样式类 */ +/* editormd-logo style classes */ .editormd-logo, .editormd-logo-1x, .editormd-logo-2x, @@ -41,6 +46,9 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + +/* editormd-logo伪元素内容 */ +/* editormd-logo pseudo-element content */ .editormd-logo:before, .editormd-logo-1x:before, .editormd-logo-2x:before, @@ -57,6 +65,8 @@ */ } +/* 不同尺寸的editormd-logo */ +/* Different sizes of editormd-logo */ .editormd-logo-1x { font-size: 1em; } @@ -93,6 +103,8 @@ font-size: 8em; } +/* 彩色editormd-logo */ +/* Colored editormd-logo */ .editormd-logo-color { color: #2196F3; -} +} \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/css/editormd.preview.css b/src/collectedstatic/mdeditor/css/editormd.preview.css index 2dc9252..b3e9e4f 100644 --- a/src/collectedstatic/mdeditor/css/editormd.preview.css +++ b/src/collectedstatic/mdeditor/css/editormd.preview.css @@ -12,12 +12,13 @@ @charset "UTF-8"; /*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */ -/*! - * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome +/*! Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */ /* FONT PATH * -------------------------- */ +/* 字体路径定义 */ +/* Font path definition */ @font-face { font-family: 'FontAwesome'; src: url("../fonts/fontawesome-webfont.eot?v=4.3.0"); @@ -25,6 +26,9 @@ font-weight: normal; font-style: normal; } + +/* FontAwesome基础样式 */ +/* FontAwesome base styles */ .fa { display: inline-block; font: normal normal normal 14px/1 FontAwesome; @@ -35,7 +39,8 @@ transform: translate(0, 0); } -/* makes the font 33% larger relative to the icon container */ +/* 使字体相对图标容器大33% */ +/* Makes the font 33% larger relative to the icon container */ .fa-lg { font-size: 1.33333333em; line-height: 0.75em; @@ -209,6 +214,7 @@ color: #ffffff; } +/* Font Awesome使用Unicode私用区(PUA)确保屏幕阅读器不会读出随机字符 */ /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen readers do not read off random characters that represent icons */ .fa-glass:before { @@ -2362,6 +2368,8 @@ } /*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */ +/* 定义editormd-logo字体 */ +/* Define editormd-logo font */ @font-face { font-family: 'editormd-logo'; src: url("../fonts/editormd-logo.eot?-5y8q6h"); @@ -2369,6 +2377,9 @@ font-weight: normal; font-style: normal; } + +/* editormd-logo样式类 */ +/* editormd-logo style classes */ .editormd-logo, .editormd-logo-1x, .editormd-logo-2x, @@ -2392,6 +2403,7 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + .editormd-logo:before, .editormd-logo-1x:before, .editormd-logo-2x:before, @@ -2449,10 +2461,15 @@ } /*! github-markdown-css | The MIT License (MIT) | Copyright (c) Sindre Sorhus (sindresorhus.com) | https://github.com/sindresorhus/github-markdown-css */ +/* 定义octicons-anchor字体 */ +/* Define octicons-anchor font */ @font-face { font-family: octicons-anchor; src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format("woff"); } + +/* Markdown主体样式 */ +/* Markdown body styles */ .markdown-body { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; @@ -3110,6 +3127,8 @@ border-color: #4183c4; } +/* Editor.md预览容器样式 */ +/* Editor.md preview container styles */ .editormd-preview-container, .editormd-html-preview { text-align: left; font-size: 14px; @@ -3119,6 +3138,7 @@ width: 100%; background-color: #fff; } + .editormd-preview-container blockquote, .editormd-html-preview blockquote { color: #666; border-left: 4px solid #ddd; @@ -3127,19 +3147,23 @@ font-size: 14px; font-style: italic; } + .editormd-preview-container p code, .editormd-html-preview p code { margin-left: 5px; margin-right: 4px; } + .editormd-preview-container abbr, .editormd-html-preview abbr { background: #ffffdd; } + .editormd-preview-container hr, .editormd-html-preview hr { height: 1px; border: none; border-top: 1px solid #ddd; background: none; } + .editormd-preview-container code, .editormd-html-preview code { border: 1px solid #ddd; background: #f6f6f6; @@ -3147,6 +3171,7 @@ border-radius: 3px; font-size: 14px; } + .editormd-preview-container pre, .editormd-html-preview pre { border: 1px solid #ddd; background: #f6f6f6; @@ -3157,35 +3182,45 @@ -o-border-radius: 3px; border-radius: 3px; } + .editormd-preview-container pre code, .editormd-html-preview pre code { padding: 0; } + .editormd-preview-container pre, .editormd-preview-container code, .editormd-preview-container kbd, .editormd-html-preview pre, .editormd-html-preview code, .editormd-html-preview kbd { font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace; } + .editormd-preview-container table thead tr, .editormd-html-preview table thead tr { background-color: #F8F8F8; } + .editormd-preview-container p.editormd-tex, .editormd-html-preview p.editormd-tex { text-align: center; } + .editormd-preview-container span.editormd-tex, .editormd-html-preview span.editormd-tex { margin: 0 5px; } + .editormd-preview-container .emoji, .editormd-html-preview .emoji { width: 24px; height: 24px; } + .editormd-preview-container .katex, .editormd-html-preview .katex { font-size: 1.4em; } + .editormd-preview-container .sequence-diagram, .editormd-preview-container .flowchart, .editormd-html-preview .sequence-diagram, .editormd-html-preview .flowchart { margin: 0 auto; text-align: center; } + .editormd-preview-container .sequence-diagram svg, .editormd-preview-container .flowchart svg, .editormd-html-preview .sequence-diagram svg, .editormd-html-preview .flowchart svg { margin: 0 auto; } + .editormd-preview-container .sequence-diagram text, .editormd-preview-container .flowchart text, .editormd-html-preview .sequence-diagram text, .editormd-html-preview .flowchart text { font-size: 15px !important; font-family: "YaHei Consolas Hybrid", Consolas, "Microsoft YaHei", "Malgun Gothic", "Segoe UI", Helvetica, Arial !important; @@ -3193,38 +3228,47 @@ /*! Pretty printing styles. Used with prettify.js. */ /* SPAN elements with the classes below are added by prettyprint. */ +/* 使用prettify.js的美化样式 */ +/* 带有以下类的SPAN元素由prettyprint添加 */ .pln { color: #000; } /* plain text */ +/* 纯文本 */ @media screen { .str { color: #080; } /* string content */ + /* 字符串内容 */ .kwd { color: #008; } /* a keyword */ + /* 关键字 */ .com { color: #800; } /* a comment */ + /* 注释 */ .typ { color: #606; } /* a type name */ + /* 类型名称 */ .lit { color: #066; } /* a literal value */ + /* 字面值 */ /* punctuation, lisp open bracket, lisp close bracket */ + /* 标点符号,Lisp开括号,Lisp闭括号 */ .pun, .opn, .clo { color: #660; } @@ -3234,28 +3278,34 @@ } /* a markup tag name */ + /* 标记标签名称 */ .atn { color: #606; } /* a markup attribute name */ + /* 标记属性名称 */ .atv { color: #080; } /* a markup attribute value */ + /* 标记属性值 */ .dec, .var { color: #606; } /* a declaration; a variable name */ + /* 声明;变量名 */ .fun { color: red; } /* a function name */ + /* 函数名 */ } /* Use higher contrast and text-weight for printable form. */ +/* 为打印形式使用更高对比度和文字粗细 */ @media print, projection { .str { color: #060; @@ -3298,18 +3348,21 @@ } } /* Put a border around prettyprinted code snippets. */ +/* 在美化代码片段周围添加边框 */ pre.prettyprint { padding: 2px; border: 1px solid #888; } /* Specify class=linenums on a pre to get line numbering */ +/* 在pre元素上指定class=linenums以获取行号 */ ol.linenums { margin-top: 0; margin-bottom: 0; } /* IE indents via margin-left */ +/* IE通过margin-left缩进 */ li.L0, li.L1, li.L2, @@ -3322,6 +3375,7 @@ li.L8 { } /* Alternate shading for lines */ +/* 行的交替着色 */ li.L1, li.L3, li.L5, @@ -3336,13 +3390,16 @@ li.L9 { white-space: pre-wrap; word-wrap: break-word; } + .editormd-preview-container ol.linenums, .editormd-html-preview ol.linenums { color: #999; padding-left: 2.5em; } + .editormd-preview-container ol.linenums li, .editormd-html-preview ol.linenums li { list-style-type: decimal; } + .editormd-preview-container ol.linenums li code, .editormd-html-preview ol.linenums li code { border: none; background: none; @@ -3353,6 +3410,7 @@ li.L9 { margin: 8px 0 12px 0; display: inline-block; } + .editormd-preview-container .editormd-toc-menu > .markdown-toc, .editormd-html-preview .editormd-toc-menu > .markdown-toc { position: relative; -webkit-border-radius: 4px; @@ -3364,6 +3422,7 @@ li.L9 { display: inline-block; font-size: 1em; } + .editormd-preview-container .editormd-toc-menu > .markdown-toc > ul, .editormd-html-preview .editormd-toc-menu > .markdown-toc > ul { width: 160%; min-width: 180px; @@ -3391,6 +3450,7 @@ li.L9 { box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* IE9+, News */ } + .editormd-preview-container .editormd-toc-menu > .markdown-toc > ul > li ul, .editormd-html-preview .editormd-toc-menu > .markdown-toc > ul > li ul { width: 100%; min-width: 180px; @@ -3403,6 +3463,7 @@ li.L9 { -o-border-radius: 4px; border-radius: 4px; } + .editormd-preview-container .editormd-toc-menu > .markdown-toc > ul > li a, .editormd-html-preview .editormd-toc-menu > .markdown-toc > ul > li a { color: #666; padding: 6px 10px; @@ -3414,12 +3475,15 @@ li.L9 { transition: background-color 500ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } + .editormd-preview-container .editormd-toc-menu > .markdown-toc > ul > li a:hover, .editormd-html-preview .editormd-toc-menu > .markdown-toc > ul > li a:hover { background-color: #f6f6f6; } + .editormd-preview-container .editormd-toc-menu > .markdown-toc li, .editormd-html-preview .editormd-toc-menu > .markdown-toc li { position: relative; } + .editormd-preview-container .editormd-toc-menu > .markdown-toc li > ul, .editormd-html-preview .editormd-toc-menu > .markdown-toc li > ul { position: absolute; top: 32px; @@ -3436,6 +3500,7 @@ li.L9 { box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* IE9+, News */ } + .editormd-preview-container .editormd-toc-menu > .markdown-toc li > ul:before, .editormd-preview-container .editormd-toc-menu > .markdown-toc li > ul:after, .editormd-html-preview .editormd-toc-menu > .markdown-toc li > ul:before, .editormd-html-preview .editormd-toc-menu > .markdown-toc li > ul:after { pointer-events: pointer-events; position: absolute; @@ -3449,28 +3514,35 @@ li.L9 { border-width: 0 6px 6px; z-index: 10; } + .editormd-preview-container .editormd-toc-menu > .markdown-toc li > ul:before, .editormd-html-preview .editormd-toc-menu > .markdown-toc li > ul:before { border-bottom-color: #ccc; } + .editormd-preview-container .editormd-toc-menu > .markdown-toc li > ul:after, .editormd-html-preview .editormd-toc-menu > .markdown-toc li > ul:after { border-bottom-color: #ffffff; top: -5px; } + .editormd-preview-container .editormd-toc-menu ul, .editormd-html-preview .editormd-toc-menu ul { list-style: none; } + .editormd-preview-container .editormd-toc-menu a, .editormd-html-preview .editormd-toc-menu a { text-decoration: none; } + .editormd-preview-container .editormd-toc-menu h1, .editormd-html-preview .editormd-toc-menu h1 { font-size: 16px; padding: 5px 0 10px 10px; line-height: 1; border-bottom: 1px solid #eee; } + .editormd-preview-container .editormd-toc-menu h1 .fa, .editormd-html-preview .editormd-toc-menu h1 .fa { padding-left: 10px; } + .editormd-preview-container .editormd-toc-menu .toc-menu-btn, .editormd-html-preview .editormd-toc-menu .toc-menu-btn { color: #666; min-width: 180px; @@ -3484,9 +3556,11 @@ li.L9 { transition: background-color 500ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } + .editormd-preview-container .editormd-toc-menu .toc-menu-btn:hover, .editormd-html-preview .editormd-toc-menu .toc-menu-btn:hover { background-color: #f6f6f6; } + .editormd-preview-container .editormd-toc-menu .toc-menu-btn .fa, .editormd-html-preview .editormd-toc-menu .toc-menu-btn .fa { float: right; padding: 3px 0 0 10px; @@ -3496,6 +3570,7 @@ li.L9 { .markdown-body .editormd-toc-menu ul { padding-left: 0; } + .markdown-body .highlight pre, .markdown-body pre { line-height: 1.6; } @@ -3513,9 +3588,11 @@ hr.editormd-page-break { height: 0; } } + .editormd-html-preview textarea { display: none; } + .editormd-html-preview hr.editormd-page-break { background: none; border: none; @@ -3544,6 +3621,7 @@ hr.editormd-page-break { transition: background-color 300ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } + .editormd-preview-close-btn:hover { background-color: #999; } @@ -3551,4 +3629,4 @@ hr.editormd-page-break { .editormd-preview-active { width: 100%; padding: 40px; -} +} \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/css/style.css b/src/collectedstatic/mdeditor/css/style.css index 0150e3b..93d40ef 100644 --- a/src/collectedstatic/mdeditor/css/style.css +++ b/src/collectedstatic/mdeditor/css/style.css @@ -1,35 +1,44 @@ +/* 全局重置样式 */ * { padding: 0; margin: 0; } +/* 盒模型设置为border-box */ *, *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } - body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{ + +/* 重置常见元素的外边距和内边距 */ +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{ margin: 0; padding: 0; } +/* HTML5元素显示设置 */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary { display: block; } +/* 音频、画布、视频元素显示设置 */ audio, canvas, video { display: inline-block; } +/* 图片样式 */ img { border: none; vertical-align: middle; } +/* 列表样式 */ ul, ol { /*list-style: none;*/ } +/* 清除浮动 */ .clear { *zoom: 1; /* for IE 6/7 */ } @@ -47,6 +56,7 @@ ul, ol { clear: both; } +/* 页面主体样式 */ body { font-size: 14px; color: #666; @@ -55,29 +65,35 @@ body { text-align: center; } +/* 布局容器 */ #layout { text-align: left; } +/* 页面头部和按钮区域 */ #layout > header, .btns { padding: 15px 0; width: 90%; margin: 0 auto; } +/* 按钮区域 */ .btns { padding-top: 0; } +/* 按钮 */ .btns button { padding: 2px 8px; } +/* 页面标题 */ #layout > header > h1 { font-size: 20px; margin-bottom: 10px; } +/* 按钮样式 */ .btns button, .btn { padding: 8px 10px; background: #fff; @@ -89,6 +105,7 @@ body { transition: background 300ms ease-out; } +/* 按钮悬停效果 */ .btns button:hover, .btn:hover { background: #f6f6f6; } \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/code-block-dialog/code-block-dialog.js b/src/collectedstatic/mdeditor/js/plugins/code-block-dialog/code-block-dialog.js index cda5651..31ef7dd 100644 --- a/src/collectedstatic/mdeditor/js/plugins/code-block-dialog/code-block-dialog.js +++ b/src/collectedstatic/mdeditor/js/plugins/code-block-dialog/code-block-dialog.js @@ -11,125 +11,150 @@ (function() { + // 工厂函数,用于定义代码块对话框插件 + // Factory function to define code block dialog plugin var factory = function (exports) { - var cmEditor; - var pluginName = "code-block-dialog"; + // CodeMirror编辑器实例 + // CodeMirror editor instance + var cmEditor; + // 插件名称 + // Plugin name + var pluginName = "code-block-dialog"; - // for CodeBlock dialog select - var codeLanguages = exports.codeLanguages = { - asp : ["ASP", "vbscript"], - actionscript : ["ActionScript(3.0)/Flash/Flex", "clike"], - bash : ["Bash/Bat", "shell"], - css : ["CSS", "css"], - c : ["C", "clike"], - cpp : ["C++", "clike"], - csharp : ["C#", "clike"], - coffeescript : ["CoffeeScript", "coffeescript"], - d : ["D", "d"], - dart : ["Dart", "dart"], - delphi : ["Delphi/Pascal", "pascal"], - erlang : ["Erlang", "erlang"], - go : ["Golang", "go"], - groovy : ["Groovy", "groovy"], - html : ["HTML", "text/html"], - java : ["Java", "clike"], - json : ["JSON", "text/json"], - javascript : ["Javascript", "javascript"], - lua : ["Lua", "lua"], - less : ["LESS", "css"], - markdown : ["Markdown", "gfm"], - "objective-c" : ["Objective-C", "clike"], - php : ["PHP", "php"], - perl : ["Perl", "perl"], - python : ["Python", "python"], - r : ["R", "r"], - rst : ["reStructedText", "rst"], - ruby : ["Ruby", "ruby"], - sql : ["SQL", "sql"], - sass : ["SASS/SCSS", "sass"], - shell : ["Shell", "shell"], - scala : ["Scala", "clike"], - swift : ["Swift", "clike"], - vb : ["VB/VBScript", "vb"], - xml : ["XML", "text/xml"], - yaml : ["YAML", "yaml"] - }; - - exports.fn.codeBlockDialog = function() { - - var _this = this; - var cm = this.cm; - var lang = this.lang; - var editor = this.editor; - var settings = this.settings; - var cursor = cm.getCursor(); - var selection = cm.getSelection(); - var classPrefix = this.classPrefix; - var dialogName = classPrefix + pluginName, dialog; - var dialogLang = lang.dialog.codeBlock; - - cm.focus(); + // 代码语言映射表,用于代码块对话框的选择列表 + // Code language mapping table for code block dialog selection list + var codeLanguages = exports.codeLanguages = { + asp : ["ASP", "vbscript"], // ASP语言 + actionscript : ["ActionScript(3.0)/Flash/Flex", "clike"], // ActionScript语言 + bash : ["Bash/Bat", "shell"], // Bash/Bat脚本 + css : ["CSS", "css"], // CSS样式表 + c : ["C", "clike"], // C语言 + cpp : ["C++", "clike"], // C++语言 + csharp : ["C#", "clike"], // C#语言 + coffeescript : ["CoffeeScript", "coffeescript"], // CoffeeScript语言 + d : ["D", "d"], // D语言 + dart : ["Dart", "dart"], // Dart语言 + delphi : ["Delphi/Pascal", "pascal"], // Delphi/Pascal语言 + erlang : ["Erlang", "erlang"], // Erlang语言 + go : ["Golang", "go"], // Go语言 + groovy : ["Groovy", "groovy"], // Groovy语言 + html : ["HTML", "text/html"], // HTML标记语言 + java : ["Java", "clike"], // Java语言 + json : ["JSON", "text/json"], // JSON数据格式 + javascript : ["Javascript", "javascript"], // JavaScript语言 + lua : ["Lua", "lua"], // Lua语言 + less : ["LESS", "css"], // LESS样式表 + markdown : ["Markdown", "gfm"], // Markdown标记语言 + "objective-c" : ["Objective-C", "clike"], // Objective-C语言 + php : ["PHP", "php"], // PHP语言 + perl : ["Perl", "perl"], // Perl语言 + python : ["Python", "python"], // Python语言 + r : ["R", "r"], // R语言 + rst : ["reStructedText", "rst"], // reStructedText标记语言 + ruby : ["Ruby", "ruby"], // Ruby语言 + sql : ["SQL", "sql"], // SQL数据库查询语言 + sass : ["SASS/SCSS", "sass"], // SASS/SCSS样式表 + shell : ["Shell", "shell"], // Shell脚本 + scala : ["Scala", "clike"], // Scala语言 + swift : ["Swift", "clike"], // Swift语言 + vb : ["VB/VBScript", "vb"], // VB/VBScript语言 + xml : ["XML", "text/xml"], // XML标记语言 + yaml : ["YAML", "yaml"] // YAML数据序列化标准 + }; + // 代码块对话框插件主函数 + // Main function of code block dialog plugin + exports.fn.codeBlockDialog = function() { + + // 获取当前编辑器实例的各种属性和方法 + // Get various properties and methods of the current editor instance + var _this = this; + var cm = this.cm; // CodeMirror实例 + var lang = this.lang; // 语言包 + var editor = this.editor; // 编辑器DOM元素 + var settings = this.settings; // 设置选项 + var cursor = cm.getCursor(); // 获取光标位置 + var selection = cm.getSelection(); // 获取选中文本 + var classPrefix = this.classPrefix; // CSS类前缀 + var dialogName = classPrefix + pluginName, dialog; // 对话框名称 + var dialogLang = lang.dialog.codeBlock; // 对话框语言包 + + // 设置焦点到CodeMirror编辑器 + // Set focus to CodeMirror editor + cm.focus(); + + // 如果对话框已存在,则显示并重置内容 + // If the dialog already exists, show it and reset the content if (editor.find("." + dialogName).length > 0) { dialog = editor.find("." + dialogName); dialog.find("option:first").attr("selected", "selected"); dialog.find("textarea").val(selection); - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); + this.dialogShowMask(dialog); // 显示对话框遮罩 + this.dialogLockScreen(); // 锁定屏幕 + dialog.show(); // 显示对话框 } else { + // 构建对话框HTML内容 + // Build dialog HTML content var dialogHTML = "
    " + dialogLang.selectLabel + "" + "
    " + ""; + // 创建对话框 + // Create dialog dialog = this.createDialog({ - name : dialogName, - title : dialogLang.title, - width : 780, - height : 565, - mask : settings.dialogShowMask, - drag : settings.dialogDraggable, - content : dialogHTML, - lockScreen : settings.dialogLockScreen, - maskStyle : { - opacity : settings.dialogMaskOpacity, - backgroundColor : settings.dialogMaskBgColor + name : dialogName, // 对话框名称 + title : dialogLang.title, // 对话框标题 + width : 780, // 对话框宽度 + height : 565, // 对话框高度 + mask : settings.dialogShowMask, // 是否显示遮罩 + drag : settings.dialogDraggable, // 是否可拖拽 + content : dialogHTML, // 对话框内容 + lockScreen : settings.dialogLockScreen, // 是否锁定屏幕 + maskStyle : { // 遮罩样式 + opacity : settings.dialogMaskOpacity, // 遮罩透明度 + backgroundColor : settings.dialogMaskBgColor // 遮罩背景色 }, - buttons : { - enter : [lang.buttons.enter, function() { - var codeTexts = this.find("textarea").val(); - var langName = this.find("select").val(); + buttons : { // 对话框按钮 + enter : [lang.buttons.enter, function() { // 确定按钮 + var codeTexts = this.find("textarea").val(); // 获取代码文本 + var langName = this.find("select").val(); // 获取选择的语言 + // 检查是否选择了语言 if (langName === "") { alert(lang.dialog.codeBlock.unselectedLanguageAlert); return false; } + // 检查代码文本是否为空 if (codeTexts === "") { alert(lang.dialog.codeBlock.codeEmptyAlert); return false; } + // 处理语言名称 langName = (langName === "other") ? "" : langName; + // 插入代码块到编辑器 cm.replaceSelection(["```" + langName, codeTexts, "```"].join("\n")); + // 如果未指定语言,设置光标位置 if (langName === "") { cm.setCursor(cursor.line, cursor.ch + 3); } + // 隐藏对话框并解锁屏幕 this.hide().lockScreen(false).hideMask(); return false; }], - cancel : [lang.buttons.cancel, function() { + cancel : [lang.buttons.cancel, function() { // 取消按钮 this.hide().lockScreen(false).hideMask(); return false; @@ -138,100 +163,112 @@ }); } - var langSelect = dialog.find("select"); - - if (langSelect.find("option").length === 1) - { - for (var key in codeLanguages) - { - var codeLang = codeLanguages[key]; - langSelect.append(""); - } - - langSelect.append(""); - } - - var mode = langSelect.find("option:selected").attr("mode"); - - var cmConfig = { - mode : (mode) ? mode : "text/html", - theme : settings.theme, - tabSize : 4, - autofocus : true, - autoCloseTags : true, - indentUnit : 4, - lineNumbers : true, - lineWrapping : true, - extraKeys : {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }}, - foldGutter : true, - gutters : ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], - matchBrackets : true, - indentWithTabs : true, - styleActiveLine : true, - styleSelectedText : true, - autoCloseBrackets : true, - showTrailingSpace : true, - highlightSelectionMatches : true - }; - - var textarea = dialog.find("textarea"); - var cmObj = dialog.find(".CodeMirror"); - - if (dialog.find(".CodeMirror").length < 1) - { - cmEditor = exports.$CodeMirror.fromTextArea(textarea[0], cmConfig); - cmObj = dialog.find(".CodeMirror"); - - cmObj.css({ - "float" : "none", - margin : "8px 0", - border : "1px solid #ddd", - fontSize : settings.fontSize, - width : "100%", - height : "390px" - }); - - cmEditor.on("change", function(cm) { - textarea.val(cm.getValue()); - }); - } - else - { - - cmEditor.setValue(cm.getSelection()); - } - - langSelect.change(function(){ - var _mode = $(this).find("option:selected").attr("mode"); - cmEditor.setOption("mode", _mode); - }); - }; - - }; + // 获取语言选择下拉框 + // Get language selection dropdown + var langSelect = dialog.find("select"); + + // 如果下拉框选项为空,则添加语言选项 + if (langSelect.find("option").length === 1) + { + // 遍历代码语言映射表,添加选项 + for (var key in codeLanguages) + { + var codeLang = codeLanguages[key]; + langSelect.append(""); + } + + // 添加"其他语言"选项 + langSelect.append(""); + } + + // 获取选中语言的模式 + var mode = langSelect.find("option:selected").attr("mode"); + + // CodeMirror配置 + var cmConfig = { + mode : (mode) ? mode : "text/html", // 编辑器模式 + theme : settings.theme, // 主题 + tabSize : 4, // Tab大小 + autofocus : true, // 自动聚焦 + autoCloseTags : true, // 自动关闭标签 + indentUnit : 4, // 缩进单位 + lineNumbers : true, // 显示行号 + lineWrapping : true, // 自动换行 + extraKeys : {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }}, // 额外快捷键 + foldGutter : true, // 代码折叠 + gutters : ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], // 代码槽 + matchBrackets : true, // 匹配括号 + indentWithTabs : true, // 使用Tab缩进 + styleActiveLine : true, // 高亮活动行 + styleSelectedText : true, // 高亮选中文本 + autoCloseBrackets : true, // 自动关闭括号 + showTrailingSpace : true, // 显示尾随空格 + highlightSelectionMatches : true // 高亮匹配选中 + }; + + // 获取文本域和CodeMirror对象 + var textarea = dialog.find("textarea"); + var cmObj = dialog.find(".CodeMirror"); + + // 如果CodeMirror对象不存在,则创建 + if (dialog.find(".CodeMirror").length < 1) + { + cmEditor = exports.$CodeMirror.fromTextArea(textarea[0], cmConfig); + cmObj = dialog.find(".CodeMirror"); + + // 设置CodeMirror样式 + cmObj.css({ + "float" : "none", + margin : "8px 0", + border : "1px solid #ddd", + fontSize : settings.fontSize, + width : "100%", + height : "390px" + }); + + // 监听代码变化事件 + cmEditor.on("change", function(cm) { + textarea.val(cm.getValue()); // 同步代码到文本域 + }); + } + else + { + // 设置CodeMirror值为选中文本 + cmEditor.setValue(cm.getSelection()); + } + + // 监听语言选择变化事件 + langSelect.change(function(){ + var _mode = $(this).find("option:selected").attr("mode"); + cmEditor.setOption("mode", _mode); // 设置CodeMirror模式 + }); + }; + + }; - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/emoji-dialog/emoji-dialog.js b/src/collectedstatic/mdeditor/js/plugins/emoji-dialog/emoji-dialog.js index 32d960d..04e4502 100644 --- a/src/collectedstatic/mdeditor/js/plugins/emoji-dialog/emoji-dialog.js +++ b/src/collectedstatic/mdeditor/js/plugins/emoji-dialog/emoji-dialog.js @@ -11,186 +11,212 @@ (function() { - var factory = function (exports) { - - var $ = jQuery; - var pluginName = "emoji-dialog"; - var emojiTabIndex = 0; - var emojiData = []; + // 工厂函数,用于定义Emoji对话框插件 + // Factory function to define Emoji dialog plugin + var factory = function (exports) { + + // jQuery对象 + var $ = jQuery; + // 插件名称 + var pluginName = "emoji-dialog"; + // Emoji选项卡索引 + var emojiTabIndex = 0; + // Emoji数据 + var emojiData = []; + // 已选择的Emoji var selecteds = []; - var logoPrefix = "editormd-logo"; - var logos = [ - logoPrefix, - logoPrefix + "-1x", - logoPrefix + "-2x", - logoPrefix + "-3x", - logoPrefix + "-4x", - logoPrefix + "-5x", - logoPrefix + "-6x", - logoPrefix + "-7x", - logoPrefix + "-8x" - ]; - - var langs = { - "zh-cn" : { - toolbar : { - emoji : "Emoji 表情" - }, - dialog : { - emoji : { - title : "Emoji 表情" - } - } - }, - "zh-tw" : { - toolbar : { - emoji : "Emoji 表情" - }, - dialog : { - emoji : { - title : "Emoji 表情" - } - } - }, - "en" : { - toolbar : { - emoji : "Emoji" - }, - dialog : { - emoji : { - title : "Emoji" - } - } - }, - "de" : { - toolbar : { - emoji : "Emoji" - }, - dialog : { - emoji : { - title : "Emoji" - } - } - } - }; - - exports.fn.emojiDialog = function() { - var _this = this; - var cm = this.cm; - var settings = _this.settings; + // Logo前缀 + var logoPrefix = "editormd-logo"; + // Logo列表 + var logos = [ + logoPrefix, + logoPrefix + "-1x", + logoPrefix + "-2x", + logoPrefix + "-3x", + logoPrefix + "-4x", + logoPrefix + "-5x", + logoPrefix + "-6x", + logoPrefix + "-7x", + logoPrefix + "-8x" + ]; + + // 多语言支持 + var langs = { + "zh-cn" : { + toolbar : { + emoji : "Emoji 表情" + }, + dialog : { + emoji : { + title : "Emoji 表情" + } + } + }, + "zh-tw" : { + toolbar : { + emoji : "Emoji 表情" + }, + dialog : { + emoji : { + title : "Emoji 表情" + } + } + }, + "en" : { + toolbar : { + emoji : "Emoji" + }, + dialog : { + emoji : { + title : "Emoji" + } + } + }, + "de" : { + toolbar : { + emoji : "Emoji" + }, + dialog : { + emoji : { + title : "Emoji" + } + } + } + }; + + // Emoji对话框插件主函数 + exports.fn.emojiDialog = function() { + // 获取当前编辑器实例的各种属性和方法 + var _this = this; + var cm = this.cm; // CodeMirror实例 + var settings = _this.settings; // 设置选项 + // 检查是否启用Emoji功能 if (!settings.emoji) { alert("settings.emoji == false"); return ; } - var path = settings.pluginPath + pluginName + "/"; - var editor = this.editor; - var cursor = cm.getCursor(); - var selection = cm.getSelection(); - var classPrefix = this.classPrefix; - - $.extend(true, this.lang, langs[this.lang.name]); - this.setToolbar(); - - var lang = this.lang; - var dialogName = classPrefix + pluginName, dialog; - var dialogLang = lang.dialog.emoji; - - var dialogContent = [ - "
    ", - "
    ", - "
    ", - ].join("\n"); - - cm.focus(); - - if (editor.find("." + dialogName).length > 0) - { + // 获取插件路径 + var path = settings.pluginPath + pluginName + "/"; + var editor = this.editor; // 编辑器DOM元素 + var cursor = cm.getCursor(); // 获取光标位置 + var selection = cm.getSelection(); // 获取选中文本 + var classPrefix = this.classPrefix; // CSS类前缀 + + // 扩展语言包并设置工具栏 + $.extend(true, this.lang, langs[this.lang.name]); + this.setToolbar(); + + // 获取语言包 + var lang = this.lang; + var dialogName = classPrefix + pluginName, dialog; // 对话框名称 + var dialogLang = lang.dialog.emoji; // Emoji对话框语言包 + + // 构建对话框内容 + var dialogContent = [ + "
    ", + "
    ", + "
    ", + ].join("\n"); + + // 设置焦点到CodeMirror编辑器 + cm.focus(); + + // 如果对话框已存在,则显示 + if (editor.find("." + dialogName).length > 0) + { dialog = editor.find("." + dialogName); - selecteds = []; - dialog.find("a").removeClass("selected"); - - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); - } - else - { - dialog = this.createDialog({ - name : dialogName, - title : dialogLang.title, - width : 800, - height : 475, - mask : settings.dialogShowMask, - drag : settings.dialogDraggable, - content : dialogContent, - lockScreen : settings.dialogLockScreen, - maskStyle : { - opacity : settings.dialogMaskOpacity, - backgroundColor : settings.dialogMaskBgColor - }, - buttons : { - enter : [lang.buttons.enter, function() { - cm.replaceSelection(selecteds.join(" ")); - this.hide().lockScreen(false).hideMask(); - - return false; - }], - cancel : [lang.buttons.cancel, function() { - this.hide().lockScreen(false).hideMask(); - - return false; - }] - } - }); - } - - var category = ["Github emoji", "Twemoji", "Font awesome", "Editor.md logo"]; - var tab = dialog.find("." + classPrefix + "tab"); - - if (tab.html() === "") - { - var head = "
      "; - - for (var i = 0; i<4; i++) { - var active = (i === 0) ? " class=\"active\"" : ""; - head += "" + category[i] + ""; - } - - head += "
    "; - - tab.append(head); - - var container = "
    "; - - for (var x = 0; x < 4; x++) + selecteds = []; + dialog.find("a").removeClass("selected"); + + this.dialogShowMask(dialog); // 显示对话框遮罩 + this.dialogLockScreen(); // 锁定屏幕 + dialog.show(); // 显示对话框 + } + else + { + // 创建对话框 + dialog = this.createDialog({ + name : dialogName, // 对话框名称 + title : dialogLang.title, // 对话框标题 + width : 800, // 对话框宽度 + height : 475, // 对话框高度 + mask : settings.dialogShowMask, // 是否显示遮罩 + drag : settings.dialogDraggable, // 是否可拖拽 + content : dialogContent, // 对话框内容 + lockScreen : settings.dialogLockScreen, // 是否锁定屏幕 + maskStyle : { // 遮罩样式 + opacity : settings.dialogMaskOpacity, // 遮罩透明度 + backgroundColor : settings.dialogMaskBgColor // 遮罩背景色 + }, + buttons : { // 对话框按钮 + enter : [lang.buttons.enter, function() { // 确定按钮 + cm.replaceSelection(selecteds.join(" ")); // 插入选中的Emoji + this.hide().lockScreen(false).hideMask(); // 隐藏对话框并解锁屏幕 + + return false; + }], + cancel : [lang.buttons.cancel, function() { // 取消按钮 + this.hide().lockScreen(false).hideMask(); // 隐藏对话框并解锁屏幕 + + return false; + }] + } + }); + } + + // Emoji分类 + var category = ["Github emoji", "Twemoji", "Font awesome", "Editor.md logo"]; + var tab = dialog.find("." + classPrefix + "tab"); + + // 如果选项卡内容为空,则创建选项卡 + if (tab.html() === "") + { + var head = "
      "; + + for (var i = 0; i<4; i++) { + var active = (i === 0) ? " class=\"active\"" : ""; + head += "" + category[i] + ""; + } + + head += "
    "; + + tab.append(head); + + var container = "
    "; + + for (var x = 0; x < 4; x++) { - var display = (x === 0) ? "" : "display:none;"; - container += "
    "; - } + var display = (x === 0) ? "" : "display:none;"; + container += "
    "; + } - container += "
    "; + container += "
    "; - tab.append(container); - } + tab.append(container); + } - var tabBoxs = tab.find("." + classPrefix + "tab-box"); + // 获取选项卡容器 + var tabBoxs = tab.find("." + classPrefix + "tab-box"); var emojiCategories = ["github-emoji", "twemoji", "font-awesome", logoPrefix]; - var drawTable = function() { + // 绘制Emoji表格 + var drawTable = function() { var cname = emojiCategories[emojiTabIndex]; - var $data = emojiData[cname]; + var $data = emojiData[cname]; var $tab = tabBoxs.eq(emojiTabIndex); - if ($tab.html() !== "") { + // 如果选项卡内容不为空,则直接返回 + if ($tab.html() !== "") { //console.log("break =>", cname); return ; } + // 分页处理 var pagination = function(data, type) { var rowNumber = (type === "editormd-logo") ? "5" : 20; var pageTotal = Math.ceil(data.length / rowNumber); @@ -208,6 +234,7 @@ { var img = "", icon = ""; + // 处理Github Emoji if (type === "github-emoji") { var src = (emoji === "+1") ? "plus1" : emoji; @@ -218,17 +245,20 @@ img = "\":""; row += "" + img + ""; } + // 处理Twemoji else if (type === "twemoji") { var twemojiSrc = exports.twemoji.path + emoji + exports.twemoji.ext; img = "\"twemoji-""; row += "" + img + ""; } + // 处理Font Awesome图标 else if (type === "font-awesome") { icon = ""; row += "" + icon + ""; } + // 处理Editor.md Logo else if (type === "editormd-logo") { icon = ""; @@ -251,6 +281,7 @@ return table; }; + // 根据选项卡索引绘制不同内容 if (emojiTabIndex === 0) { for (var i = 0, len = $data.length; i < len; i++) @@ -265,73 +296,76 @@ $tab.append(pagination($data, cname)); } - $tab.find("." + classPrefix + "emoji-btn").bind(exports.mouseOrTouch("click", "touchend"), function() { - $(this).toggleClass("selected"); - - if ($(this).hasClass("selected")) - { - selecteds.push($(this).attr("value")); - } - }); - }; - - if (emojiData.length < 1) - { - if (typeof dialog.loading === "function") { + // 绑定Emoji按钮点击事件 + $tab.find("." + classPrefix + "emoji-btn").bind(exports.mouseOrTouch("click", "touchend"), function() { + $(this).toggleClass("selected"); + + if ($(this).hasClass("selected")) + { + selecteds.push($(this).attr("value")); + } + }); + }; + + // 如果Emoji数据为空,则从JSON文件加载 + if (emojiData.length < 1) + { + if (typeof dialog.loading === "function") { dialog.loading(true); } - $.getJSON(path + "emoji.json?temp=" + Math.random(), function(json) { + $.getJSON(path + "emoji.json?temp=" + Math.random(), function(json) { - if (typeof dialog.loading === "function") { + if (typeof dialog.loading === "function") { dialog.loading(false); } - emojiData = json; + emojiData = json; emojiData[logoPrefix] = logos; - drawTable(); - }); - } - else - { - drawTable(); - } - - tab.find("li").bind(exports.mouseOrTouch("click", "touchend"), function() { - var $this = $(this); - emojiTabIndex = $this.index(); - - $this.addClass("active").siblings().removeClass("active"); - tabBoxs.eq(emojiTabIndex).show().siblings().hide(); - drawTable(); - }); - }; - - }; + drawTable(); + }); + } + else + { + drawTable(); + } + + // 绑定选项卡点击事件 + tab.find("li").bind(exports.mouseOrTouch("click", "touchend"), function() { + var $this = $(this); + emojiTabIndex = $this.index(); + + $this.addClass("active").siblings().removeClass("active"); + tabBoxs.eq(emojiTabIndex).show().siblings().hide(); + drawTable(); + }); + }; + + }; - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/goto-line-dialog/goto-line-dialog.js b/src/collectedstatic/mdeditor/js/plugins/goto-line-dialog/goto-line-dialog.js index c64f25e..9d865cc 100644 --- a/src/collectedstatic/mdeditor/js/plugins/goto-line-dialog/goto-line-dialog.js +++ b/src/collectedstatic/mdeditor/js/plugins/goto-line-dialog/goto-line-dialog.js @@ -11,159 +11,177 @@ (function() { - var factory = function (exports) { - - var $ = jQuery; - var pluginName = "goto-line-dialog"; - - var langs = { - "zh-cn" : { - toolbar : { - "goto-line" : "跳转到行" - }, - dialog : { - "goto-line" : { - title : "跳转到行", - label : "请输入行号", - error : "错误:" - } - } - }, - "zh-tw" : { - toolbar : { - "goto-line" : "跳轉到行" - }, - dialog : { - "goto-line" : { - title : "跳轉到行", - label : "請輸入行號", - error : "錯誤:" - } - } - }, - "en" : { - toolbar : { - "goto-line" : "Goto line" - }, - dialog : { - "goto-line" : { - title : "Goto line", - label : "Enter a line number, range ", - error : "Error: " - } - } - }, - "de" : { - toolbar : { - "goto-line" : "Gehe zu Zeile" - }, - dialog : { - "goto-line" : { - title : "Gehe zu Zeile", - label : "Eine Zeile oder Zeilenbereich eingeben", - error : "Fehler: " - } - } - } - }; - - exports.fn.gotoLineDialog = function() { - var _this = this; - var cm = this.cm; - var editor = this.editor; - var settings = this.settings; - var path = settings.pluginPath + pluginName +"/"; - var classPrefix = this.classPrefix; - var dialogName = classPrefix + pluginName, dialog; - - $.extend(true, this.lang, langs[this.lang.name]); - this.setToolbar(); - - var lang = this.lang; - var dialogLang = lang.dialog["goto-line"]; - var lineCount = cm.lineCount(); - - dialogLang.error += dialogLang.label + " 1-" + lineCount; - - if (editor.find("." + dialogName).length < 1) - { - var dialogContent = [ - "
    ", - "

    " + dialogLang.label + " 1-" + lineCount +"   

    ", - "
    " - ].join("\n"); - - dialog = this.createDialog({ - name : dialogName, - title : dialogLang.title, - width : 400, - height : 180, - mask : settings.dialogShowMask, - drag : settings.dialogDraggable, - content : dialogContent, - lockScreen : settings.dialogLockScreen, - maskStyle : { - opacity : settings.dialogMaskOpacity, - backgroundColor : settings.dialogMaskBgColor - }, - buttons : { - enter : [lang.buttons.enter, function() { - var line = parseInt(this.find("[data-line-number]").val()); - - if (line < 1 || line > lineCount) { - alert(dialogLang.error); - - return false; - } - - _this.gotoLine(line); - + // 工厂函数,用于定义跳转到行对话框插件 + // Factory function to define goto line dialog plugin + var factory = function (exports) { + + // jQuery对象 + var $ = jQuery; + // 插件名称 + var pluginName = "goto-line-dialog"; + + // 多语言支持 + var langs = { + "zh-cn" : { + toolbar : { + "goto-line" : "跳转到行" + }, + dialog : { + "goto-line" : { + title : "跳转到行", + label : "请输入行号", + error : "错误:" + } + } + }, + "zh-tw" : { + toolbar : { + "goto-line" : "跳轉到行" + }, + dialog : { + "goto-line" : { + title : "跳轉到行", + label : "請輸入行號", + error : "錯誤:" + } + } + }, + "en" : { + toolbar : { + "goto-line" : "Goto line" + }, + dialog : { + "goto-line" : { + title : "Goto line", + label : "Enter a line number, range ", + error : "Error: " + } + } + }, + "de" : { + toolbar : { + "goto-line" : "Gehe zu Zeile" + }, + dialog : { + "goto-line" : { + title : "Gehe zu Zeile", + label : "Eine Zeile oder Zeilenbereich eingeben", + error : "Fehler: " + } + } + } + }; + + // 跳转到行对话框插件主函数 + exports.fn.gotoLineDialog = function() { + // 获取当前编辑器实例的各种属性和方法 + var _this = this; + var cm = this.cm; // CodeMirror实例 + var editor = this.editor; // 编辑器DOM元素 + var settings = this.settings; // 设置选项 + var path = settings.pluginPath + pluginName +"/"; // 插件路径 + var classPrefix = this.classPrefix; // CSS类前缀 + var dialogName = classPrefix + pluginName, dialog; // 对话框名称 + + // 扩展语言包并设置工具栏 + $.extend(true, this.lang, langs[this.lang.name]); + this.setToolbar(); + + // 获取语言包 + var lang = this.lang; + var dialogLang = lang.dialog["goto-line"]; + var lineCount = cm.lineCount(); // 获取总行数 + + // 构造错误信息 + dialogLang.error += dialogLang.label + " 1-" + lineCount; + + // 如果对话框不存在,则创建 + if (editor.find("." + dialogName).length < 1) + { + // 构建对话框内容 + var dialogContent = [ + "
    ", + "

    " + dialogLang.label + " 1-" + lineCount +"   

    ", + "
    " + ].join("\n"); + + // 创建对话框 + dialog = this.createDialog({ + name : dialogName, // 对话框名称 + title : dialogLang.title, // 对话框标题 + width : 400, // 对话框宽度 + height : 180, // 对话框高度 + mask : settings.dialogShowMask, // 是否显示遮罩 + drag : settings.dialogDraggable, // 是否可拖拽 + content : dialogContent, // 对话框内容 + lockScreen : settings.dialogLockScreen, // 是否锁定屏幕 + maskStyle : { // 遮罩样式 + opacity : settings.dialogMaskOpacity, // 遮罩透明度 + backgroundColor : settings.dialogMaskBgColor // 遮罩背景色 + }, + buttons : { // 对话框按钮 + enter : [lang.buttons.enter, function() { // 确定按钮 + var line = parseInt(this.find("[data-line-number]").val()); // 获取行号 + + // 检查行号是否有效 + if (line < 1 || line > lineCount) { + alert(dialogLang.error); + + return false; + } + + // 跳转到指定行 + _this.gotoLine(line); + + // 隐藏对话框并解锁屏幕 this.hide().lockScreen(false).hideMask(); return false; }], - cancel : [lang.buttons.cancel, function() { + cancel : [lang.buttons.cancel, function() { // 取消按钮 this.hide().lockScreen(false).hideMask(); return false; }] - } - }); - } + } + }); + } - dialog = editor.find("." + dialogName); + // 获取对话框元素 + dialog = editor.find("." + dialogName); - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); - }; + // 显示对话框 + this.dialogShowMask(dialog); + this.dialogLockScreen(); + dialog.show(); + }; - }; + }; - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/help-dialog/help-dialog.js b/src/collectedstatic/mdeditor/js/plugins/help-dialog/help-dialog.js index a21a31d..c90db9d 100644 --- a/src/collectedstatic/mdeditor/js/plugins/help-dialog/help-dialog.js +++ b/src/collectedstatic/mdeditor/js/plugins/help-dialog/help-dialog.js @@ -11,92 +11,106 @@ (function() { - var factory = function (exports) { + // 工厂函数,用于定义帮助对话框插件 + // Factory function to define help dialog plugin + var factory = function (exports) { - var $ = jQuery; - var pluginName = "help-dialog"; + // jQuery对象 + var $ = jQuery; + // 插件名称 + var pluginName = "help-dialog"; - exports.fn.helpDialog = function() { - var _this = this; - var lang = this.lang; - var editor = this.editor; - var settings = this.settings; - var path = settings.pluginPath + pluginName + "/"; - var classPrefix = this.classPrefix; - var dialogName = classPrefix + pluginName, dialog; - var dialogLang = lang.dialog.help; + // 帮助对话框插件主函数 + exports.fn.helpDialog = function() { + // 获取当前编辑器实例的各种属性和方法 + var _this = this; + var lang = this.lang; // 语言包 + var editor = this.editor; // 编辑器DOM元素 + var settings = this.settings; // 设置选项 + var path = settings.pluginPath + pluginName + "/"; // 插件路径 + var classPrefix = this.classPrefix; // CSS类前缀 + var dialogName = classPrefix + pluginName, dialog; // 对话框名称 + var dialogLang = lang.dialog.help; // 帮助对话框语言包 - if (editor.find("." + dialogName).length < 1) - { - var dialogContent = "
    "; + // 如果对话框不存在,则创建 + if (editor.find("." + dialogName).length < 1) + { + // 构建对话框内容 + var dialogContent = "
    "; - dialog = this.createDialog({ - name : dialogName, - title : dialogLang.title, - width : 840, - height : 540, - mask : settings.dialogShowMask, - drag : settings.dialogDraggable, - content : dialogContent, - lockScreen : settings.dialogLockScreen, - maskStyle : { - opacity : settings.dialogMaskOpacity, - backgroundColor : settings.dialogMaskBgColor - }, - buttons : { - close : [lang.buttons.close, function() { - this.hide().lockScreen(false).hideMask(); - - return false; - }] - } - }); - } + // 创建对话框 + dialog = this.createDialog({ + name : dialogName, // 对话框名称 + title : dialogLang.title, // 对话框标题 + width : 840, // 对话框宽度 + height : 540, // 对话框高度 + mask : settings.dialogShowMask, // 是否显示遮罩 + drag : settings.dialogDraggable, // 是否可拖拽 + content : dialogContent, // 对话框内容 + lockScreen : settings.dialogLockScreen, // 是否锁定屏幕 + maskStyle : { // 遮罩样式 + opacity : settings.dialogMaskOpacity, // 遮罩透明度 + backgroundColor : settings.dialogMaskBgColor // 遮罩背景色 + }, + buttons : { // 对话框按钮 + close : [lang.buttons.close, function() { // 关闭按钮 + this.hide().lockScreen(false).hideMask(); + + return false; + }] + } + }); + } - dialog = editor.find("." + dialogName); + // 获取对话框元素 + dialog = editor.find("." + dialogName); - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); + // 显示对话框 + this.dialogShowMask(dialog); + this.dialogLockScreen(); + dialog.show(); - var helpContent = dialog.find(".markdown-body"); + // 获取帮助内容容器 + var helpContent = dialog.find(".markdown-body"); - if (helpContent.html() === "") - { - $.get(path + "help.md", function(text) { - var md = exports.$marked(text); - helpContent.html(md); + // 如果帮助内容为空,则从help.md文件加载 + if (helpContent.html() === "") + { + $.get(path + "help.md", function(text) { + var md = exports.$marked(text); // 使用marked解析Markdown + helpContent.html(md); // 设置帮助内容 + // 设置链接在新窗口打开 helpContent.find("a").attr("target", "_blank"); - }); - } - }; + }); + } + }; - }; + }; - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/html-entities-dialog/html-entities-dialog.js b/src/collectedstatic/mdeditor/js/plugins/html-entities-dialog/html-entities-dialog.js index 78a2317..7aadabe 100644 --- a/src/collectedstatic/mdeditor/js/plugins/html-entities-dialog/html-entities-dialog.js +++ b/src/collectedstatic/mdeditor/js/plugins/html-entities-dialog/html-entities-dialog.js @@ -11,163 +11,181 @@ (function() { - var factory = function (exports) { - - var $ = jQuery; - var pluginName = "html-entities-dialog"; - var selecteds = []; - var entitiesData = []; - - exports.fn.htmlEntitiesDialog = function() { - var _this = this; - var cm = this.cm; - var lang = _this.lang; - var settings = _this.settings; - var path = settings.pluginPath + pluginName + "/"; - var editor = this.editor; - var cursor = cm.getCursor(); - var selection = cm.getSelection(); - var classPrefix = _this.classPrefix; - - var dialogName = classPrefix + "dialog-" + pluginName, dialog; - var dialogLang = lang.dialog.htmlEntities; - - var dialogContent = [ - '
    ', - '
    ', - '
    ', - '
    ', - ].join("\r\n"); - - cm.focus(); - - if (editor.find("." + dialogName).length > 0) - { + // 工厂函数,用于定义HTML实体对话框插件 + // Factory function to define HTML entities dialog plugin + var factory = function (exports) { + + // jQuery对象 + var $ = jQuery; + // 插件名称 + var pluginName = "html-entities-dialog"; + // 已选择的实体 + var selecteds = []; + // 实体数据 + var entitiesData = []; + + // HTML实体对话框插件主函数 + exports.fn.htmlEntitiesDialog = function() { + // 获取当前编辑器实例的各种属性和方法 + var _this = this; + var cm = this.cm; // CodeMirror实例 + var lang = _this.lang; // 语言包 + var settings = _this.settings; // 设置选项 + var path = settings.pluginPath + pluginName + "/"; // 插件路径 + var editor = this.editor; // 编辑器DOM元素 + var cursor = cm.getCursor(); // 获取光标位置 + var selection = cm.getSelection(); // 获取选中文本 + var classPrefix = _this.classPrefix; // CSS类前缀 + + // 对话框名称和语言包 + var dialogName = classPrefix + "dialog-" + pluginName, dialog; + var dialogLang = lang.dialog.htmlEntities; + + // 构建对话框内容 + var dialogContent = [ + '
    ', + '
    ', + '
    ', + '
    ', + ].join("\r\n"); + + // 设置焦点到CodeMirror编辑器 + cm.focus(); + + // 如果对话框已存在,则显示 + if (editor.find("." + dialogName).length > 0) + { dialog = editor.find("." + dialogName); - selecteds = []; - dialog.find("a").removeClass("selected"); - - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); - } - else - { - dialog = this.createDialog({ - name : dialogName, - title : dialogLang.title, - width : 800, - height : 475, - mask : settings.dialogShowMask, - drag : settings.dialogDraggable, - content : dialogContent, - lockScreen : settings.dialogLockScreen, - maskStyle : { - opacity : settings.dialogMaskOpacity, - backgroundColor : settings.dialogMaskBgColor - }, - buttons : { - enter : [lang.buttons.enter, function() { - cm.replaceSelection(selecteds.join(" ")); - this.hide().lockScreen(false).hideMask(); - - return false; - }], - cancel : [lang.buttons.cancel, function() { - this.hide().lockScreen(false).hideMask(); - - return false; - }] - } - }); - } - - var table = dialog.find("." + classPrefix + "grid-table"); - - var drawTable = function() { - - if (entitiesData.length < 1) return ; - - var rowNumber = 20; - var pageTotal = Math.ceil(entitiesData.length / rowNumber); - - table.html(""); - - for (var i = 0; i < pageTotal; i++) - { - var row = "
    "; - - for (var x = 0; x < rowNumber; x++) - { - var entity = entitiesData[(i * rowNumber) + x]; - - if (typeof entity !== "undefined") - { - var name = entity.name.replace("&", "&"); - - row += "" + name + ""; - } - } - - row += "
    "; - - table.append(row); - } - - dialog.find("." + classPrefix + "html-entity-btn").bind(exports.mouseOrTouch("click", "touchend"), function() { - $(this).toggleClass("selected"); - - if ($(this).hasClass("selected")) - { - selecteds.push($(this).attr("value")); - } - }); - }; - - if (entitiesData.length < 1) - { - if (typeof (dialog.loading) == "function") dialog.loading(true); - - $.getJSON(path + pluginName.replace("-dialog", "") + ".json", function(json) { - - if (typeof (dialog.loading) == "function") dialog.loading(false); - - entitiesData = json; - drawTable(); - }); - } - else - { - drawTable(); - } - }; - - }; + selecteds = []; + dialog.find("a").removeClass("selected"); + + this.dialogShowMask(dialog); // 显示对话框遮罩 + this.dialogLockScreen(); // 锁定屏幕 + dialog.show(); // 显示对话框 + } + else + { + // 创建对话框 + dialog = this.createDialog({ + name : dialogName, // 对话框名称 + title : dialogLang.title, // 对话框标题 + width : 800, // 对话框宽度 + height : 475, // 对话框高度 + mask : settings.dialogShowMask, // 是否显示遮罩 + drag : settings.dialogDraggable, // 是否可拖拽 + content : dialogContent, // 对话框内容 + lockScreen : settings.dialogLockScreen, // 是否锁定屏幕 + maskStyle : { // 遮罩样式 + opacity : settings.dialogMaskOpacity, // 遮罩透明度 + backgroundColor : settings.dialogMaskBgColor // 遮罩背景色 + }, + buttons : { // 对话框按钮 + enter : [lang.buttons.enter, function() { // 确定按钮 + cm.replaceSelection(selecteds.join(" ")); // 插入选中的实体 + this.hide().lockScreen(false).hideMask(); // 隐藏对话框并解锁屏幕 + + return false; + }], + cancel : [lang.buttons.cancel, function() { // 取消按钮 + this.hide().lockScreen(false).hideMask(); // 隐藏对话框并解锁屏幕 + + return false; + }] + } + }); + } + + // 获取表格容器 + var table = dialog.find("." + classPrefix + "grid-table"); + + // 绘制表格 + var drawTable = function() { + + // 如果实体数据为空,则直接返回 + if (entitiesData.length < 1) return ; + + var rowNumber = 20; + var pageTotal = Math.ceil(entitiesData.length / rowNumber); + + table.html(""); + + for (var i = 0; i < pageTotal; i++) + { + var row = "
    "; + + for (var x = 0; x < rowNumber; x++) + { + var entity = entitiesData[(i * rowNumber) + x]; + + if (typeof entity !== "undefined") + { + var name = entity.name.replace("&", "&"); + + row += "" + name + ""; + } + } + + row += "
    "; + + table.append(row); + } + + // 绑定HTML实体按钮点击事件 + dialog.find("." + classPrefix + "html-entity-btn").bind(exports.mouseOrTouch("click", "touchend"), function() { + $(this).toggleClass("selected"); + + if ($(this).hasClass("selected")) + { + selecteds.push($(this).attr("value")); + } + }); + }; + + // 如果实体数据为空,则从JSON文件加载 + if (entitiesData.length < 1) + { + if (typeof (dialog.loading) == "function") dialog.loading(true); + + $.getJSON(path + pluginName.replace("-dialog", "") + ".json", function(json) { + + if (typeof (dialog.loading) == "function") dialog.loading(false); + + entitiesData = json; + drawTable(); + }); + } + else + { + drawTable(); + } + }; + + }; - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/image-dialog/image-dialog.js b/src/collectedstatic/mdeditor/js/plugins/image-dialog/image-dialog.js index 0f8d817..edfb4ec 100644 --- a/src/collectedstatic/mdeditor/js/plugins/image-dialog/image-dialog.js +++ b/src/collectedstatic/mdeditor/js/plugins/image-dialog/image-dialog.js @@ -11,41 +11,59 @@ (function() { + // 工厂函数,用于定义图片对话框插件 + // Factory function to define image dialog plugin var factory = function (exports) { - var pluginName = "image-dialog"; + // 插件名称 + // Plugin name + var pluginName = "image-dialog"; - exports.fn.imageDialog = function() { + // 图片对话框插件主函数 + // Main function of image dialog plugin + exports.fn.imageDialog = function() { + // 获取当前编辑器实例的各种属性和方法 + // Get various properties and methods of the current editor instance var _this = this; - var cm = this.cm; - var lang = this.lang; - var editor = this.editor; - var settings = this.settings; - var cursor = cm.getCursor(); - var selection = cm.getSelection(); - var imageLang = lang.dialog.image; - var classPrefix = this.classPrefix; - var iframeName = classPrefix + "image-iframe"; - var dialogName = classPrefix + pluginName, dialog; - - cm.focus(); - + var cm = this.cm; // CodeMirror实例 + var lang = this.lang; // 语言包 + var editor = this.editor; // 编辑器DOM元素 + var settings = this.settings; // 设置选项 + var cursor = cm.getCursor(); // 获取光标位置 + var selection = cm.getSelection(); // 获取选中文本 + var imageLang = lang.dialog.image; // 图片对话框语言包 + var classPrefix = this.classPrefix; // CSS类前缀 + var iframeName = classPrefix + "image-iframe"; // iframe名称 + var dialogName = classPrefix + pluginName, dialog; // 对话框名称 + + // 设置焦点到CodeMirror编辑器 + // Set focus to CodeMirror editor + cm.focus(); + + // 显示/隐藏加载遮罩 + // Show/hide loading mask var loading = function(show) { var _loading = dialog.find("." + classPrefix + "dialog-mask"); _loading[(show) ? "show" : "hide"](); }; + // 如果对话框不存在,则创建 + // If the dialog does not exist, create it if (editor.find("." + dialogName).length < 1) { + // 生成唯一标识符 var guid = (new Date).getTime(); + // 构造上传URL var action = settings.imageUploadURL + (settings.imageUploadURL.indexOf("?") >= 0 ? "&" : "?") + "guid=" + guid; + // 处理跨域上传 if (settings.crossDomainUpload) { action += "&callback=" + settings.uploadCallbackURL + "&dialog_id=editormd-image-dialog-" + guid; } + // 构建对话框内容 var dialogContent = ( (settings.imageUpload) ? "
    " : "
    " ) + ( (settings.imageUpload) ? "" : "" ) + "" + @@ -64,35 +82,37 @@ "
    " + ( (settings.imageUpload) ? "" : "
    "); - //var imageFooterHTML = ""; - + // 创建对话框 dialog = this.createDialog({ - title : imageLang.title, - width : (settings.imageUpload) ? 465 : 380, - height : 254, - name : dialogName, - content : dialogContent, - mask : settings.dialogShowMask, - drag : settings.dialogDraggable, - lockScreen : settings.dialogLockScreen, - maskStyle : { - opacity : settings.dialogMaskOpacity, - backgroundColor : settings.dialogMaskBgColor + title : imageLang.title, // 对话框标题 + width : (settings.imageUpload) ? 465 : 380, // 对话框宽度 + height : 254, // 对话框高度 + name : dialogName, // 对话框名称 + content : dialogContent, // 对话框内容 + mask : settings.dialogShowMask, // 是否显示遮罩 + drag : settings.dialogDraggable, // 是否可拖拽 + lockScreen : settings.dialogLockScreen, // 是否锁定屏幕 + maskStyle : { // 遮罩样式 + opacity : settings.dialogMaskOpacity, // 遮罩透明度 + backgroundColor : settings.dialogMaskBgColor // 遮罩背景色 }, - buttons : { - enter : [lang.buttons.enter, function() { - var url = this.find("[data-url]").val(); - var alt = this.find("[data-alt]").val(); - var link = this.find("[data-link]").val(); + buttons : { // 对话框按钮 + enter : [lang.buttons.enter, function() { // 确定按钮 + var url = this.find("[data-url]").val(); // 获取图片URL + var alt = this.find("[data-alt]").val(); // 获取图片描述 + var link = this.find("[data-link]").val(); // 获取链接地址 + // 检查图片URL是否为空 if (url === "") { alert(imageLang.imageURLEmpty); return false; } - var altAttr = (alt !== "") ? " \"" + alt + "\"" : ""; + // 构造alt属性 + var altAttr = (alt !== "") ? " \"" + alt + "\"" : ""; + // 根据是否包含链接构造Markdown图片格式 if (link === "" || link === "http://") { cm.replaceSelection("![" + alt + "](" + url + altAttr + ")"); @@ -102,16 +122,18 @@ cm.replaceSelection("[![" + alt + "](" + url + altAttr + ")](" + link + altAttr + ")"); } + // 如果描述为空,设置光标位置 if (alt === "") { cm.setCursor(cursor.line, cursor.ch + 2); } + // 隐藏对话框并解锁屏幕 this.hide().lockScreen(false).hideMask(); return false; }], - cancel : [lang.buttons.cancel, function() { + cancel : [lang.buttons.cancel, function() { // 取消按钮 this.hide().lockScreen(false).hideMask(); return false; @@ -119,47 +141,62 @@ } }); + // 设置对话框ID dialog.attr("id", classPrefix + "image-dialog-" + guid); - if (!settings.imageUpload) { + // 如果不支持图片上传,直接返回 + if (!settings.imageUpload) { return ; } - var fileInput = dialog.find("[name=\"" + classPrefix + "image-file\"]"); + // 获取文件输入框 + var fileInput = dialog.find("[name=\"" + classPrefix + "image-file\"]"); - fileInput.bind("change", function() { - var fileName = fileInput.val(); - var isImage = new RegExp("(\\.(" + settings.imageFormats.join("|") + "))$"); // /(\.(webp|jpg|jpeg|gif|bmp|png))$/ + // 绑定文件选择变化事件 + fileInput.bind("change", function() { + var fileName = fileInput.val(); + // 检查文件扩展名是否为图片格式 + var isImage = new RegExp("(\\.(" + settings.imageFormats.join("|") + "))$"); // /(\.(webp|jpg|jpeg|gif|bmp|png))$/ - if (fileName === "") - { - alert(imageLang.uploadFileEmpty); + // 检查文件名是否为空 + if (fileName === "") + { + alert(imageLang.uploadFileEmpty); return false; - } + } + // 检查文件格式是否允许 if (!isImage.test(fileName)) - { - alert(imageLang.formatNotAllowed + settings.imageFormats.join(", ")); + { + alert(imageLang.formatNotAllowed + settings.imageFormats.join(", ")); return false; - } + } + // 显示加载遮罩 loading(true); + // 提交处理函数 var submitHandler = function() { + // 获取上传iframe var uploadIframe = document.getElementById(iframeName); + // 绑定iframe加载完成事件 uploadIframe.onload = function() { + // 隐藏加载遮罩 loading(false); + // 获取iframe中的内容 var body = (uploadIframe.contentWindow ? uploadIframe.contentWindow : uploadIframe.contentDocument).document.body; var json = (body.innerText) ? body.innerText : ( (body.textContent) ? body.textContent : null); + // 解析JSON响应 json = (typeof JSON.parse !== "undefined") ? JSON.parse(json) : eval("(" + json + ")"); + // 处理非跨域上传响应 if(!settings.crossDomainUpload) { if (json.success === 1) @@ -176,46 +213,49 @@ }; }; + // 绑定并触发提交按钮点击事件 dialog.find("[type=\"submit\"]").bind("click", submitHandler).trigger("click"); - }); + }); } - dialog = editor.find("." + dialogName); - dialog.find("[type=\"text\"]").val(""); - dialog.find("[type=\"file\"]").val(""); - dialog.find("[data-link]").val("http://"); + // 重置对话框表单内容 + dialog = editor.find("." + dialogName); + dialog.find("[type=\"text\"]").val(""); + dialog.find("[type=\"file\"]").val(""); + dialog.find("[data-link]").val("http://"); - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); + // 显示对话框 + this.dialogShowMask(dialog); + this.dialogLockScreen(); + dialog.show(); - }; + }; - }; + }; - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/link-dialog/link-dialog.js b/src/collectedstatic/mdeditor/js/plugins/link-dialog/link-dialog.js index 6957563..4223f23 100644 --- a/src/collectedstatic/mdeditor/js/plugins/link-dialog/link-dialog.js +++ b/src/collectedstatic/mdeditor/js/plugins/link-dialog/link-dialog.js @@ -11,36 +11,50 @@ (function() { + // 工厂函数,用于定义链接对话框插件 + // Factory function to define link dialog plugin var factory = function (exports) { - var pluginName = "link-dialog"; - - exports.fn.linkDialog = function() { - - var _this = this; - var cm = this.cm; - var editor = this.editor; - var settings = this.settings; - var selection = cm.getSelection(); - var lang = this.lang; - var linkLang = lang.dialog.link; - var classPrefix = this.classPrefix; - var dialogName = classPrefix + pluginName, dialog; - - cm.focus(); - + // 插件名称 + // Plugin name + var pluginName = "link-dialog"; + + // 链接对话框插件主函数 + // Main function of link dialog plugin + exports.fn.linkDialog = function() { + + // 获取当前编辑器实例的各种属性和方法 + // Get various properties and methods of the current editor instance + var _this = this; + var cm = this.cm; // CodeMirror实例 + var editor = this.editor; // 编辑器DOM元素 + var settings = this.settings; // 设置选项 + var selection = cm.getSelection(); // 获取选中文本 + var lang = this.lang; // 语言包 + var linkLang = lang.dialog.link; // 链接对话框语言包 + var classPrefix = this.classPrefix; // CSS类前缀 + var dialogName = classPrefix + pluginName, dialog; // 对话框名称 + + // 设置焦点到CodeMirror编辑器 + // Set focus to CodeMirror editor + cm.focus(); + + // 如果对话框已存在,则显示并重置内容 + // If the dialog already exists, show it and reset the content if (editor.find("." + dialogName).length > 0) { dialog = editor.find("." + dialogName); dialog.find("[data-url]").val("http://"); dialog.find("[data-title]").val(selection); - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); + this.dialogShowMask(dialog); // 显示对话框遮罩 + this.dialogLockScreen(); // 锁定屏幕 + dialog.show(); // 显示对话框 } else { + // 构建对话框HTML内容 + // Build dialog HTML content var dialogHTML = "
    " + "" + "" + @@ -50,23 +64,26 @@ "
    " + "
    "; + // 创建对话框 + // Create dialog dialog = this.createDialog({ - title : linkLang.title, - width : 380, - height : 211, - content : dialogHTML, - mask : settings.dialogShowMask, - drag : settings.dialogDraggable, - lockScreen : settings.dialogLockScreen, - maskStyle : { - opacity : settings.dialogMaskOpacity, - backgroundColor : settings.dialogMaskBgColor + title : linkLang.title, // 对话框标题 + width : 380, // 对话框宽度 + height : 211, // 对话框高度 + content : dialogHTML, // 对话框内容 + mask : settings.dialogShowMask, // 是否显示遮罩 + drag : settings.dialogDraggable, // 是否可拖拽 + lockScreen : settings.dialogLockScreen, // 是否锁定屏幕 + maskStyle : { // 遮罩样式 + opacity : settings.dialogMaskOpacity, // 遮罩透明度 + backgroundColor : settings.dialogMaskBgColor // 遮罩背景色 }, - buttons : { - enter : [lang.buttons.enter, function() { - var url = this.find("[data-url]").val(); - var title = this.find("[data-title]").val(); + buttons : { // 对话框按钮 + enter : [lang.buttons.enter, function() { // 确定按钮 + var url = this.find("[data-url]").val(); // 获取链接地址 + var title = this.find("[data-title]").val(); // 获取链接标题 + // 检查链接地址是否为空 if (url === "http://" || url === "") { alert(linkLang.urlEmpty); @@ -79,55 +96,59 @@ return false; }*/ + // 构造Markdown链接格式 var str = "[" + title + "](" + url + " \"" + title + "\")"; + // 如果标题为空,使用简化格式 if (title == "") { str = "[" + url + "](" + url + ")"; } + // 插入链接到编辑器 cm.replaceSelection(str); + // 隐藏对话框并解锁屏幕 this.hide().lockScreen(false).hideMask(); return false; }], - cancel : [lang.buttons.cancel, function() { + cancel : [lang.buttons.cancel, function() { // 取消按钮 this.hide().lockScreen(false).hideMask(); return false; }] } }); - } - }; + } + }; - }; + }; - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/plugin-template.js b/src/collectedstatic/mdeditor/js/plugins/plugin-template.js index 8e30169..6be0b4d 100644 --- a/src/collectedstatic/mdeditor/js/plugins/plugin-template.js +++ b/src/collectedstatic/mdeditor/js/plugins/plugin-template.js @@ -11,101 +11,106 @@ (function() { + // 工厂函数,用于定义插件模板 + // Factory function to define plugin template var factory = function (exports) { - var $ = jQuery; // if using module loader(Require.js/Sea.js). + // jQuery对象 + var $ = jQuery; // if using module loader(Require.js/Sea.js). - var langs = { - "zh-cn" : { - toolbar : { - table : "表格" - }, - dialog : { - table : { - title : "添加表格", - cellsLabel : "单元格数", - alignLabel : "对齐方式", - rows : "行数", - cols : "列数", - aligns : ["默认", "左对齐", "居中对齐", "右对齐"] - } - } - }, - "zh-tw" : { - toolbar : { - table : "添加表格" - }, - dialog : { - table : { - title : "添加表格", - cellsLabel : "單元格數", - alignLabel : "對齊方式", - rows : "行數", - cols : "列數", - aligns : ["默認", "左對齊", "居中對齊", "右對齊"] - } - } - }, - "en" : { - toolbar : { - table : "Tables" - }, - dialog : { - table : { - title : "Tables", - cellsLabel : "Cells", - alignLabel : "Align", - rows : "Rows", - cols : "Cols", - aligns : ["Default", "Left align", "Center align", "Right align"] - } - } - } - }; + // 多语言支持 + var langs = { + "zh-cn" : { + toolbar : { + table : "表格" + }, + dialog : { + table : { + title : "添加表格", + cellsLabel : "单元格数", + alignLabel : "对齐方式", + rows : "行数", + cols : "列数", + aligns : ["默认", "左对齐", "居中对齐", "右对齐"] + } + } + }, + "zh-tw" : { + toolbar : { + table : "添加表格" + }, + dialog : { + table : { + title : "添加表格", + cellsLabel : "單元格數", + alignLabel : "對齊方式", + rows : "行數", + cols : "列數", + aligns : ["默認", "左對齊", "居中對齊", "右對齊"] + } + } + }, + "en" : { + toolbar : { + table : "Tables" + }, + dialog : { + table : { + title : "Tables", + cellsLabel : "Cells", + alignLabel : "Align", + rows : "Rows", + cols : "Cols", + aligns : ["Default", "Left align", "Center align", "Right align"] + } + } + } + }; - exports.fn.htmlEntities = function() { - /* - var _this = this; // this == the current instance object of Editor.md - var lang = _this.lang; - var settings = _this.settings; - var editor = this.editor; - var cursor = cm.getCursor(); - var selection = cm.getSelection(); - var classPrefix = this.classPrefix; + // HTML实体插件主函数 + exports.fn.htmlEntities = function() { + /* + var _this = this; // this == the current instance object of Editor.md + var lang = _this.lang; + var settings = _this.settings; + var editor = this.editor; + var cursor = cm.getCursor(); + var selection = cm.getSelection(); + var classPrefix = this.classPrefix; - $.extend(true, this.lang, langs[this.lang.name]); // l18n - this.setToolbar(); + $.extend(true, this.lang, langs[this.lang.name]); // l18n + this.setToolbar(); - cm.focus(); - */ - //.... - }; + cm.focus(); + */ + //.... + }; - }; + }; - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("./../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/preformatted-text-dialog/preformatted-text-dialog.js b/src/collectedstatic/mdeditor/js/plugins/preformatted-text-dialog/preformatted-text-dialog.js index 812c2e7..7aa131c 100644 --- a/src/collectedstatic/mdeditor/js/plugins/preformatted-text-dialog/preformatted-text-dialog.js +++ b/src/collectedstatic/mdeditor/js/plugins/preformatted-text-dialog/preformatted-text-dialog.js @@ -11,61 +11,73 @@ (function() { + // 工厂函数,用于定义预格式化文本对话框插件 + // Factory function to define preformatted text dialog plugin var factory = function (exports) { - var cmEditor; - var pluginName = "preformatted-text-dialog"; + // CodeMirror编辑器实例 + var cmEditor; + // 插件名称 + var pluginName = "preformatted-text-dialog"; - exports.fn.preformattedTextDialog = function() { + // 预格式化文本对话框插件主函数 + exports.fn.preformattedTextDialog = function() { + // 获取当前编辑器实例的各种属性和方法 var _this = this; - var cm = this.cm; - var lang = this.lang; - var editor = this.editor; - var settings = this.settings; - var cursor = cm.getCursor(); - var selection = cm.getSelection(); - var classPrefix = this.classPrefix; - var dialogLang = lang.dialog.preformattedText; - var dialogName = classPrefix + pluginName, dialog; - - cm.focus(); - + var cm = this.cm; // CodeMirror实例 + var lang = this.lang; // 语言包 + var editor = this.editor; // 编辑器DOM元素 + var settings = this.settings; // 设置选项 + var cursor = cm.getCursor(); // 获取光标位置 + var selection = cm.getSelection(); // 获取选中文本 + var classPrefix = this.classPrefix; // CSS类前缀 + var dialogLang = lang.dialog.preformattedText; // 预格式化文本对话框语言包 + var dialogName = classPrefix + pluginName, dialog; // 对话框名称 + + // 设置焦点到CodeMirror编辑器 + cm.focus(); + + // 如果对话框已存在,则显示并重置内容 if (editor.find("." + dialogName).length > 0) { dialog = editor.find("." + dialogName); dialog.find("textarea").val(selection); - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); + this.dialogShowMask(dialog); // 显示对话框遮罩 + this.dialogLockScreen(); // 锁定屏幕 + dialog.show(); // 显示对话框 } else { + // 构建对话框内容 var dialogContent = ""; + // 创建对话框 dialog = this.createDialog({ - name : dialogName, - title : dialogLang.title, - width : 780, - height : 540, - mask : settings.dialogShowMask, - drag : settings.dialogDraggable, - content : dialogContent, - lockScreen : settings.dialogLockScreen, - maskStyle : { - opacity : settings.dialogMaskOpacity, - backgroundColor : settings.dialogMaskBgColor + name : dialogName, // 对话框名称 + title : dialogLang.title, // 对话框标题 + width : 780, // 对话框宽度 + height : 540, // 对话框高度 + mask : settings.dialogShowMask, // 是否显示遮罩 + drag : settings.dialogDraggable, // 是否可拖拽 + content : dialogContent, // 对话框内容 + lockScreen : settings.dialogLockScreen, // 是否锁定屏幕 + maskStyle : { // 遮罩样式 + opacity : settings.dialogMaskOpacity, // 遮罩透明度 + backgroundColor : settings.dialogMaskBgColor // 遮罩背景色 }, - buttons : { - enter : [lang.buttons.enter, function() { - var codeTexts = this.find("textarea").val(); + buttons : { // 对话框按钮 + enter : [lang.buttons.enter, function() { // 确定按钮 + var codeTexts = this.find("textarea").val(); // 获取代码文本 + // 检查代码文本是否为空 if (codeTexts === "") { alert(dialogLang.emptyAlert); return false; } + // 为每行代码添加4个空格的缩进 codeTexts = codeTexts.split("\n"); for (var i in codeTexts) @@ -75,17 +87,20 @@ codeTexts = codeTexts.join("\n"); + // 如果光标不在行首,添加换行符 if (cursor.ch !== 0) { codeTexts = "\r\n\r\n" + codeTexts; } + // 插入预格式化文本到编辑器 cm.replaceSelection(codeTexts); + // 隐藏对话框并解锁屏幕 this.hide().lockScreen(false).hideMask(); return false; }], - cancel : [lang.buttons.cancel, function() { + cancel : [lang.buttons.cancel, function() { // 取消按钮 this.hide().lockScreen(false).hideMask(); return false; @@ -93,80 +108,86 @@ } }); } - - var cmConfig = { - mode : "text/html", - theme : settings.theme, - tabSize : 4, - autofocus : true, - autoCloseTags : true, - indentUnit : 4, - lineNumbers : true, - lineWrapping : true, - extraKeys : {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }}, - foldGutter : true, - gutters : ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], - matchBrackets : true, - indentWithTabs : true, - styleActiveLine : true, - styleSelectedText : true, - autoCloseBrackets : true, - showTrailingSpace : true, - highlightSelectionMatches : true - }; - - var textarea = dialog.find("textarea"); - var cmObj = dialog.find(".CodeMirror"); - - if (dialog.find(".CodeMirror").length < 1) - { - cmEditor = exports.$CodeMirror.fromTextArea(textarea[0], cmConfig); - cmObj = dialog.find(".CodeMirror"); - - cmObj.css({ - "float" : "none", - margin : "0 0 5px", - border : "1px solid #ddd", - fontSize : settings.fontSize, - width : "100%", - height : "410px" - }); - - cmEditor.on("change", function(cm) { - textarea.val(cm.getValue()); - }); - } - else - { - cmEditor.setValue(cm.getSelection()); - } - }; - - }; - - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + + // CodeMirror配置 + var cmConfig = { + mode : "text/html", // 编辑器模式 + theme : settings.theme, // 主题 + tabSize : 4, // Tab大小 + autofocus : true, // 自动聚焦 + autoCloseTags : true, // 自动关闭标签 + indentUnit : 4, // 缩进单位 + lineNumbers : true, // 显示行号 + lineWrapping : true, // 自动换行 + extraKeys : {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }}, // 额外快捷键 + foldGutter : true, // 代码折叠 + gutters : ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], // 代码槽 + matchBrackets : true, // 匹配括号 + indentWithTabs : true, // 使用Tab缩进 + styleActiveLine : true, // 高亮活动行 + styleSelectedText : true, // 高亮选中文本 + autoCloseBrackets : true, // 自动关闭括号 + showTrailingSpace : true, // 显示尾随空格 + highlightSelectionMatches : true // 高亮匹配选中 + }; + + // 获取文本域和CodeMirror对象 + var textarea = dialog.find("textarea"); + var cmObj = dialog.find(".CodeMirror"); + + // 如果CodeMirror对象不存在,则创建 + if (dialog.find(".CodeMirror").length < 1) + { + cmEditor = exports.$CodeMirror.fromTextArea(textarea[0], cmConfig); + cmObj = dialog.find(".CodeMirror"); + + // 设置CodeMirror样式 + cmObj.css({ + "float" : "none", + margin : "0 0 5px", + border : "1px solid #ddd", + fontSize : settings.fontSize, + width : "100%", + height : "410px" + }); + + // 监听代码变化事件 + cmEditor.on("change", function(cm) { + textarea.val(cm.getValue()); // 同步代码到文本域 + }); + } + else + { + // 设置CodeMirror值为选中文本 + cmEditor.setValue(cm.getSelection()); + } + }; + + }; + + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/reference-link-dialog/reference-link-dialog.js b/src/collectedstatic/mdeditor/js/plugins/reference-link-dialog/reference-link-dialog.js index 6eb9d72..7c99746 100644 --- a/src/collectedstatic/mdeditor/js/plugins/reference-link-dialog/reference-link-dialog.js +++ b/src/collectedstatic/mdeditor/js/plugins/reference-link-dialog/reference-link-dialog.js @@ -11,28 +11,37 @@ (function() { + // 工厂函数,用于定义引用链接对话框插件 + // Factory function to define reference link dialog plugin var factory = function (exports) { - var pluginName = "reference-link-dialog"; - var ReLinkId = 1; + // 插件名称 + var pluginName = "reference-link-dialog"; + // 引用链接ID计数器 + var ReLinkId = 1; - exports.fn.referenceLinkDialog = function() { + // 引用链接对话框插件主函数 + exports.fn.referenceLinkDialog = function() { + // 获取当前编辑器实例的各种属性和方法 var _this = this; - var cm = this.cm; - var lang = this.lang; - var editor = this.editor; - var settings = this.settings; - var cursor = cm.getCursor(); - var selection = cm.getSelection(); - var dialogLang = lang.dialog.referenceLink; - var classPrefix = this.classPrefix; - var dialogName = classPrefix + pluginName, dialog; - - cm.focus(); - + var cm = this.cm; // CodeMirror实例 + var lang = this.lang; // 语言包 + var editor = this.editor; // 编辑器DOM元素 + var settings = this.settings; // 设置选项 + var cursor = cm.getCursor(); // 获取光标位置 + var selection = cm.getSelection(); // 获取选中文本 + var dialogLang = lang.dialog.referenceLink; // 引用链接对话框语言包 + var classPrefix = this.classPrefix; // CSS类前缀 + var dialogName = classPrefix + pluginName, dialog; // 对话框名称 + + // 设置焦点到CodeMirror编辑器 + cm.focus(); + + // 如果对话框不存在,则创建 if (editor.find("." + dialogName).length < 1) { + // 构建对话框HTML内容 var dialogHTML = "
    " + "" + "" + @@ -48,60 +57,69 @@ "
    " + "
    "; + // 创建对话框 dialog = this.createDialog({ - name : dialogName, - title : dialogLang.title, - width : 380, - height : 296, - content : dialogHTML, - mask : settings.dialogShowMask, - drag : settings.dialogDraggable, - lockScreen : settings.dialogLockScreen, - maskStyle : { - opacity : settings.dialogMaskOpacity, - backgroundColor : settings.dialogMaskBgColor + name : dialogName, // 对话框名称 + title : dialogLang.title, // 对话框标题 + width : 380, // 对话框宽度 + height : 296, // 对话框高度 + content : dialogHTML, // 对话框内容 + mask : settings.dialogShowMask, // 是否显示遮罩 + drag : settings.dialogDraggable, // 是否可拖拽 + lockScreen : settings.dialogLockScreen, // 是否锁定屏幕 + maskStyle : { // 遮罩样式 + opacity : settings.dialogMaskOpacity, // 遮罩透明度 + backgroundColor : settings.dialogMaskBgColor // 遮罩背景色 }, - buttons : { - enter : [lang.buttons.enter, function() { - var name = this.find("[data-name]").val(); - var url = this.find("[data-url]").val(); - var rid = this.find("[data-url-id]").val(); - var title = this.find("[data-title]").val(); - + buttons : { // 对话框按钮 + enter : [lang.buttons.enter, function() { // 确定按钮 + var name = this.find("[data-name]").val(); // 获取引用名称 + var url = this.find("[data-url]").val(); // 获取URL + var rid = this.find("[data-url-id]").val(); // 获取URL ID + var title = this.find("[data-title]").val(); // 获取标题 + + // 检查引用名称是否为空 if (name === "") { alert(dialogLang.nameEmpty); return false; } + // 检查URL ID是否为空 if (rid === "") { alert(dialogLang.idEmpty); return false; } + // 检查URL是否为空 if (url === "http://" || url === "") { alert(dialogLang.urlEmpty); return false; } + // 插入引用链接到编辑器 //cm.replaceSelection("[" + title + "][" + name + "]\n[" + name + "]: " + url + ""); cm.replaceSelection("[" + name + "][" + rid + "]"); + // 如果没有选中文本,设置光标位置 if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } - title = (title === "") ? "" : " \"" + title + "\""; + // 处理标题 + title = (title === "") ? "" : " \"" + title + "\""; - cm.setValue(cm.getValue() + "\n[" + rid + "]: " + url + title + ""); + // 在文档末尾添加引用链接定义 + cm.setValue(cm.getValue() + "\n[" + rid + "]: " + url + title + ""); + // 隐藏对话框并解锁屏幕 this.hide().lockScreen(false).hideMask(); return false; }], - cancel : [lang.buttons.cancel, function() { + cancel : [lang.buttons.cancel, function() { // 取消按钮 this.hide().lockScreen(false).hideMask(); return false; @@ -110,44 +128,47 @@ }); } - dialog = editor.find("." + dialogName); - dialog.find("[data-name]").val("[" + ReLinkId + "]"); - dialog.find("[data-url-id]").val(""); - dialog.find("[data-url]").val("http://"); - dialog.find("[data-title]").val(selection); + // 重置对话框表单内容 + dialog = editor.find("." + dialogName); + dialog.find("[data-name]").val("[" + ReLinkId + "]"); + dialog.find("[data-url-id]").val(""); + dialog.find("[data-url]").val("http://"); + dialog.find("[data-title]").val(selection); - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); + // 显示对话框 + this.dialogShowMask(dialog); + this.dialogLockScreen(); + dialog.show(); - ReLinkId++; - }; + // 增加引用链接ID计数器 + ReLinkId++; + }; - }; + }; - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/js/plugins/table-dialog/table-dialog.js b/src/collectedstatic/mdeditor/js/plugins/table-dialog/table-dialog.js index 026a324..e774dc8 100644 --- a/src/collectedstatic/mdeditor/js/plugins/table-dialog/table-dialog.js +++ b/src/collectedstatic/mdeditor/js/plugins/table-dialog/table-dialog.js @@ -11,208 +11,233 @@ (function() { - var factory = function (exports) { - - var $ = jQuery; - var pluginName = "table-dialog"; - - var langs = { - "zh-cn" : { - toolbar : { - table : "表格" - }, - dialog : { - table : { - title : "添加表格", - cellsLabel : "单元格数", - alignLabel : "对齐方式", - rows : "行数", - cols : "列数", - aligns : ["默认", "左对齐", "居中对齐", "右对齐"] - } - } - }, - "zh-tw" : { - toolbar : { - table : "添加表格" - }, - dialog : { - table : { - title : "添加表格", - cellsLabel : "單元格數", - alignLabel : "對齊方式", - rows : "行數", - cols : "列數", - aligns : ["默認", "左對齊", "居中對齊", "右對齊"] - } - } - }, - "en" : { - toolbar : { - table : "Tables" - }, - dialog : { - table : { - title : "Tables", - cellsLabel : "Cells", - alignLabel : "Align", - rows : "Rows", - cols : "Cols", - aligns : ["Default", "Left align", "Center align", "Right align"] - } - } - } - }; - - exports.fn.tableDialog = function() { - var _this = this; - var cm = this.cm; - var editor = this.editor; - var settings = this.settings; - var path = settings.path + "../plugins/" + pluginName +"/"; - var classPrefix = this.classPrefix; - var dialogName = classPrefix + pluginName, dialog; - - $.extend(true, this.lang, langs[this.lang.name]); - this.setToolbar(); - - var lang = this.lang; - var dialogLang = lang.dialog.table; - - var dialogContent = [ - "
    ", - "", - dialogLang.rows + "   ", - dialogLang.cols + "
    ", - "", - "
    ", - "
    " - ].join("\n"); - - if (editor.find("." + dialogName).length > 0) - { + // 工厂函数,用于定义表格对话框插件 + // Factory function to define table dialog plugin + var factory = function (exports) { + + // jQuery对象 + var $ = jQuery; + // 插件名称 + var pluginName = "table-dialog"; + + // 多语言支持 + var langs = { + "zh-cn" : { + toolbar : { + table : "表格" + }, + dialog : { + table : { + title : "添加表格", + cellsLabel : "单元格数", + alignLabel : "对齐方式", + rows : "行数", + cols : "列数", + aligns : ["默认", "左对齐", "居中对齐", "右对齐"] + } + } + }, + "zh-tw" : { + toolbar : { + table : "添加表格" + }, + dialog : { + table : { + title : "添加表格", + cellsLabel : "單元格數", + alignLabel : "對齊方式", + rows : "行數", + cols : "列數", + aligns : ["默認", "左對齊", "居中對齊", "右對齊"] + } + } + }, + "en" : { + toolbar : { + table : "Tables" + }, + dialog : { + table : { + title : "Tables", + cellsLabel : "Cells", + alignLabel : "Align", + rows : "Rows", + cols : "Cols", + aligns : ["Default", "Left align", "Center align", "Right align"] + } + } + } + }; + + // 表格对话框插件主函数 + exports.fn.tableDialog = function() { + // 获取当前编辑器实例的各种属性和方法 + var _this = this; + var cm = this.cm; // CodeMirror实例 + var editor = this.editor; // 编辑器DOM元素 + var settings = this.settings; // 设置选项 + var path = settings.path + "../plugins/" + pluginName +"/"; // 插件路径 + var classPrefix = this.classPrefix; // CSS类前缀 + var dialogName = classPrefix + pluginName, dialog; // 对话框名称 + + // 扩展语言包并设置工具栏 + $.extend(true, this.lang, langs[this.lang.name]); + this.setToolbar(); + + // 获取语言包 + var lang = this.lang; + var dialogLang = lang.dialog.table; + + // 构建对话框内容 + var dialogContent = [ + "
    ", + "", + dialogLang.rows + "   ", + dialogLang.cols + "
    ", + "", + "
    ", + "
    " + ].join("\n"); + + // 如果对话框已存在,则显示 + if (editor.find("." + dialogName).length > 0) + { dialog = editor.find("." + dialogName); - this.dialogShowMask(dialog); - this.dialogLockScreen(); - dialog.show(); - } - else - { - dialog = this.createDialog({ - name : dialogName, - title : dialogLang.title, - width : 360, - height : 226, - mask : settings.dialogShowMask, - drag : settings.dialogDraggable, - content : dialogContent, - lockScreen : settings.dialogLockScreen, - maskStyle : { - opacity : settings.dialogMaskOpacity, - backgroundColor : settings.dialogMaskBgColor - }, - buttons : { - enter : [lang.buttons.enter, function() { - var rows = parseInt(this.find("[data-rows]").val()); - var cols = parseInt(this.find("[data-cols]").val()); - var align = this.find("[name=\"table-align\"]:checked").val(); - var table = ""; - var hrLine = "------------"; - - var alignSign = { - _default : hrLine, - left : ":" + hrLine, - center : ":" + hrLine + ":", - right : hrLine + ":" - }; - - if ( rows > 1 && cols > 0) - { - for (var r = 0, len = rows; r < len; r++) - { - var row = []; - var head = []; - - for (var c = 0, len2 = cols; c < len2; c++) - { - if (r === 1) { - head.push(alignSign[align]); - } - - row.push(" "); - } - - if (r === 1) { - table += "| " + head.join(" | ") + " |" + "\n"; - } - - table += "| " + row.join( (cols === 1) ? "" : " | " ) + " |" + "\n"; - } - } - - cm.replaceSelection(table); - + this.dialogShowMask(dialog); // 显示对话框遮罩 + this.dialogLockScreen(); // 锁定屏幕 + dialog.show(); // 显示对话框 + } + else + { + // 创建对话框 + dialog = this.createDialog({ + name : dialogName, // 对话框名称 + title : dialogLang.title, // 对话框标题 + width : 360, // 对话框宽度 + height : 226, // 对话框高度 + mask : settings.dialogShowMask, // 是否显示遮罩 + drag : settings.dialogDraggable, // 是否可拖拽 + content : dialogContent, // 对话框内容 + lockScreen : settings.dialogLockScreen, // 是否锁定屏幕 + maskStyle : { // 遮罩样式 + opacity : settings.dialogMaskOpacity, // 遮罩透明度 + backgroundColor : settings.dialogMaskBgColor // 遮罩背景色 + }, + buttons : { // 对话框按钮 + enter : [lang.buttons.enter, function() { // 确定按钮 + var rows = parseInt(this.find("[data-rows]").val()); // 获取行数 + var cols = parseInt(this.find("[data-cols]").val()); // 获取列数 + var align = this.find("[name=\"table-align\"]:checked").val(); // 获取对齐方式 + var table = ""; // 表格内容 + var hrLine = "------------"; // 分隔线 + + // 对齐标记映射 + var alignSign = { + _default : hrLine, // 默认对齐 + left : ":" + hrLine, // 左对齐 + center : ":" + hrLine + ":", // 居中对齐 + right : hrLine + ":" // 右对齐 + }; + + // 生成表格Markdown代码 + if ( rows > 1 && cols > 0) + { + for (var r = 0, len = rows; r < len; r++) + { + var row = []; // 表格行 + var head = []; // 表头行 + + for (var c = 0, len2 = cols; c < len2; c++) + { + // 第二行生成表头分隔线 + if (r === 1) { + head.push(alignSign[align]); + } + + row.push(" "); + } + + // 添加表头分隔行 + if (r === 1) { + table += "| " + head.join(" | ") + " |" + "\n"; + } + + // 添加普通行 + table += "| " + row.join( (cols === 1) ? "" : " | " ) + " |" + "\n"; + } + } + + // 插入表格到编辑器 + cm.replaceSelection(table); + + // 隐藏对话框并解锁屏幕 this.hide().lockScreen(false).hideMask(); return false; }], - cancel : [lang.buttons.cancel, function() { + cancel : [lang.buttons.cancel, function() { // 取消按钮 this.hide().lockScreen(false).hideMask(); return false; }] - } - }); - } - - var faBtns = dialog.find(".fa-btns"); - - if (faBtns.html() === "") - { - var icons = ["align-justify", "align-left", "align-center", "align-right"]; - var _lang = dialogLang.aligns; - var values = ["_default", "left", "center", "right"]; - - for (var i = 0, len = icons.length; i < len; i++) - { - var checked = (i === 0) ? " checked=\"checked\"" : ""; - var btn = ""; - - faBtns.append(btn); - } - } - }; - - }; + } + }); + } + + // 获取对齐方式按钮容器 + var faBtns = dialog.find(".fa-btns"); + + // 如果按钮容器为空,则创建对齐方式按钮 + if (faBtns.html() === "") + { + // 图标列表 + var icons = ["align-justify", "align-left", "align-center", "align-right"]; + // 语言文本 + var _lang = dialogLang.aligns; + // 值列表 + var values = ["_default", "left", "center", "right"]; + + // 创建对齐方式按钮 + for (var i = 0, len = icons.length; i < len; i++) + { + var checked = (i === 0) ? " checked=\"checked\"" : ""; + var btn = ""; + + faBtns.append(btn); + } + } + }; + + }; - // CommonJS/Node.js - if (typeof require === "function" && typeof exports === "object" && typeof module === "object") + // CommonJS/Node.js + if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } - else if (typeof define === "function") // AMD/CMD/Sea.js + else if (typeof define === "function") // AMD/CMD/Sea.js { - if (define.amd) { // for Require.js + if (define.amd) { // for Require.js - define(["editormd"], function(editormd) { + define(["editormd"], function(editormd) { factory(editormd); }); - } else { // for Sea.js - define(function(require) { + } else { // for Sea.js + define(function(require) { var editormd = require("../../editormd"); factory(editormd); }); - } - } - else - { + } + } + else + { factory(window.editormd); - } + } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/languages/de.js b/src/collectedstatic/mdeditor/languages/de.js index a58850f..81ba1d8 100644 --- a/src/collectedstatic/mdeditor/languages/de.js +++ b/src/collectedstatic/mdeditor/languages/de.js @@ -1,106 +1,120 @@ (function(){ + // 工厂函数,用于定义德语语言包 + // Factory function to define German language package var factory = function (exports) { + // 定义德语语言配置对象 + // Define German language configuration object var lang = { - name : "de", - description : "Open source online Markdown editor.", - tocTitle : "Inhalt", + name : "de", // 语言名称 - Language name + description : "Open source online Markdown editor.", // 描述 - Description + tocTitle : "Inhalt", // 目录标题 - Table of contents title toolbar : { - undo : "Rückgängig(Ctrl+Z)", - redo : "Wiederholen(Ctrl+Y)", - bold : "Fett", - del : "Durchgestrichen", - italic : "Kursiv", - quote : "Block Zitat", - ucwords : "Erster Buchstabe des Worts groß", - uppercase : "Auswahltext in Großbuchstaben konvertieren", - lowercase : "Auswahltext in Kleinbuchstaben konvertieren", - h1 : "Überschrift 1", - h2 : "Überschrift 2", - h3 : "Überschrift 3", - h4 : "Überschrift 4", - h5 : "Überschrift 5", - h6 : "Überschrift 6", - "list-ul" : "Ungeordnete Liste", - "list-ol" : "Geordnete Liste", - hr : "Horizontale Linie", - link : "Link", - "reference-link" : "Referenzlink", - image : "Bild", - code : "Code inline", - "preformatted-text" : "Vorformatierter Text / Codeblock (Tab Einrückung)", - "code-block" : "Codeblock (Multi-languages)", - table : "Tabellen", - datetime : "Datum & Zeit", - emoji : "Emoji", - "html-entities" : "HTML Entities", - pagebreak : "Seitenumbruch", - watch : "Unwatch", - unwatch : "Watch", - preview : "HTML Vorschau (Shift + ESC zum verlassen)", - fullscreen : "Vollbild (ESC zum verlassen)", - clear : "Löschen", - search : "Suchen", - help : "Hilfe", - info : "Über " + exports.title + // 工具栏各按钮的德语翻译 + // German translations for toolbar buttons + undo : "Rückgängig(Ctrl+Z)", // 撤销 + redo : "Wiederholen(Ctrl+Y)", // 重做 + bold : "Fett", // 粗体 + del : "Durchgestrichen", // 删除线 + italic : "Kursiv", // 斜体 + quote : "Block Zitat", // 块引用 + ucwords : "Erster Buchstabe des Worts groß", // 单词首字母大写 + uppercase : "Auswahltext in Großbuchstaben konvertieren", // 转换为大写 + lowercase : "Auswahltext in Kleinbuchstaben konvertieren", // 转换为小写 + h1 : "Überschrift 1", // 标题1 + h2 : "Überschrift 2", // 标题2 + h3 : "Überschrift 3", // 标题3 + h4 : "Überschrift 4", // 标题4 + h5 : "Überschrift 5", // 标题5 + h6 : "Überschrift 6", // 标题6 + "list-ul" : "Ungeordnete Liste", // 无序列表 + "list-ol" : "Geordnete Liste", // 有序列表 + hr : "Horizontale Linie", // 水平线 + link : "Link", // 链接 + "reference-link" : "Referenzlink", // 引用链接 + image : "Bild", // 图片 + code : "Code inline", // 行内代码 + "preformatted-text" : "Vorformatierter Text / Codeblock (Tab Einrückung)", // 预格式化文本/代码块 + "code-block" : "Codeblock (Multi-languages)", // 代码块(多语言) + table : "Tabellen", // 表格 + datetime : "Datum & Zeit", // 日期时间 + emoji : "Emoji", // 表情符号 + "html-entities" : "HTML Entities", // HTML实体 + pagebreak : "Seitenumbruch", // 分页符 + watch : "Unwatch", // 关闭实时预览 + unwatch : "Watch", // 开启实时预览 + preview : "HTML Vorschau (Shift + ESC zum verlassen)", // HTML预览 + fullscreen : "Vollbild (ESC zum verlassen)", // 全屏 + clear : "Löschen", // 清除 + search : "Suchen", // 搜索 + help : "Hilfe", // 帮助 + info : "Über " + exports.title // 关于信息 }, buttons : { - enter : "Eingeben", - cancel : "Abbrechen", - close : "Schließen" + // 对话框按钮文本 + // Dialog button texts + enter : "Eingeben", // 确定按钮 + cancel : "Abbrechen", // 取消按钮 + close : "Schließen" // 关闭按钮 }, dialog : { + // 各种对话框的德语翻译 + // German translations for various dialogs link : { - title : "Link", - url : "Adresse", - urlTitle : "Titel", - urlEmpty : "Fehler: Bitte Link Adresse angeben." + title : "Link", // 链接对话框标题 + url : "Adresse", // URL地址标签 + urlTitle : "Titel", // 标题标签 + urlEmpty : "Fehler: Bitte Link Adresse angeben." // URL为空时的错误提示 }, referenceLink : { - title : "Referenzlink", - name : "Name", - url : "Adresse", - urlId : "ID", - urlTitle : "Titel", - nameEmpty: "Fehler: Referenzlink Name kann nicht leer sein.", - idEmpty : "Fehler: Bitte Referenzlink ID angeben.", - urlEmpty : "Fehler: Bitte Referenzlink URL Adresse angeben." + title : "Referenzlink", // 引用链接对话框标题 + name : "Name", // 名称标签 + url : "Adresse", // URL地址标签 + urlId : "ID", // ID标签 + urlTitle : "Titel", // 标题标签 + nameEmpty: "Fehler: Referenzlink Name kann nicht leer sein.", // 名称为空时的错误提示 + idEmpty : "Fehler: Bitte Referenzlink ID angeben.", // ID为空时的错误提示 + urlEmpty : "Fehler: Bitte Referenzlink URL Adresse angeben." // URL为空时的错误提示 }, image : { - title : "Bild", - url : "Adresse", - link : "Link", - alt : "Titel", - uploadButton : "Hochladen", - imageURLEmpty : "Fehler: Bild URL Adresse darf nciht leer sein.", - uploadFileEmpty : "Fehler: Bild darf nicht leer sein!", - formatNotAllowed : "Fehler: nur Bilddatei upload möglich. Bitte im Format:" + title : "Bild", // 图片对话框标题 + url : "Adresse", // URL地址标签 + link : "Link", // 链接标签 + alt : "Titel", // 标题(alt属性)标签 + uploadButton : "Hochladen", // 上传按钮 + imageURLEmpty : "Fehler: Bild URL Adresse darf nciht leer sein.", // 图片URL为空时的错误提示 + uploadFileEmpty : "Fehler: Bild darf nicht leer sein!", // 上传文件为空时的错误提示 + formatNotAllowed : "Fehler: nur Bilddatei upload möglich. Bitte im Format:" // 文件格式不允许时的错误提示 }, preformattedText : { - title : "Vorformatierter Text / Codeblock ", - emptyAlert : "Fehler: Bitte den vorformatierten text oder Code Inhalt eingeben.", - placeholder : "Codiere jetzt ..." + title : "Vorformatierter Text / Codeblock ", // 预格式化文本对话框标题 + emptyAlert : "Fehler: Bitte den vorformatierten text oder Code Inhalt eingeben.", // 内容为空时的错误提示 + placeholder : "Codiere jetzt ..." // 占位符文本 }, codeBlock : { - title : "Codeblock", - selectLabel : "Sprachen: ", - selectDefaultText : "Programmiersprache wählen...", - otherLanguage : "Andere sprachen", - unselectedLanguageAlert : "Fehler: Bitte Programmiersprache wählen.", - codeEmptyAlert : "Fehler: Bitte den Code Inhalt eingeben.", - placeholder : "Codiere jetzt ..." + title : "Codeblock", // 代码块对话框标题 + selectLabel : "Sprachen: ", // 语言选择标签 + selectDefaultText : "Programmiersprache wählen...", // 默认选择文本 + otherLanguage : "Andere sprachen", // 其他语言选项 + unselectedLanguageAlert : "Fehler: Bitte Programmiersprache wählen.", // 未选择语言时的错误提示 + codeEmptyAlert : "Fehler: Bitte den Code Inhalt eingeben.", // 代码内容为空时的错误提示 + placeholder : "Codiere jetzt ..." // 占位符文本 }, htmlEntities : { - title : "HTML Entities" + title : "HTML Entities" // HTML实体对话框标题 }, help : { - title : "Hilfe" + title : "Hilfe" // 帮助对话框标题 } } }; + // 将语言配置导出 + // Export language configuration exports.defaults.lang = lang; }; + // 根据不同的模块加载方式导出语言包 + // Export language package according to different module loading methods // CommonJS/Node.js if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { diff --git a/src/collectedstatic/mdeditor/languages/en.js b/src/collectedstatic/mdeditor/languages/en.js index 6af70c9..1cb0daf 100644 --- a/src/collectedstatic/mdeditor/languages/en.js +++ b/src/collectedstatic/mdeditor/languages/en.js @@ -1,106 +1,120 @@ (function(){ + // 工厂函数,用于定义英语语言包 + // Factory function to define English language package var factory = function (exports) { + // 定义英语语言配置对象 + // Define English language configuration object var lang = { - name : "en", - description : "Open source online Markdown editor.", - tocTitle : "Table of Contents", + name : "en", // 语言名称 - Language name + description : "Open source online Markdown editor.", // 描述 - Description + tocTitle : "Table of Contents", // 目录标题 - Table of contents title toolbar : { - undo : "Undo(Ctrl+Z)", - redo : "Redo(Ctrl+Y)", - bold : "Bold", - del : "Strikethrough", - italic : "Italic", - quote : "Block quote", - ucwords : "Words first letter convert to uppercase", - uppercase : "Selection text convert to uppercase", - lowercase : "Selection text convert to lowercase", - h1 : "Heading 1", - h2 : "Heading 2", - h3 : "Heading 3", - h4 : "Heading 4", - h5 : "Heading 5", - h6 : "Heading 6", - "list-ul" : "Unordered list", - "list-ol" : "Ordered list", - hr : "Horizontal rule", - link : "Link", - "reference-link" : "Reference link", - image : "Image", - code : "Code inline", - "preformatted-text" : "Preformatted text / Code block (Tab indent)", - "code-block" : "Code block (Multi-languages)", - table : "Tables", - datetime : "Datetime", - emoji : "Emoji", - "html-entities" : "HTML Entities", - pagebreak : "Page break", - watch : "Unwatch", - unwatch : "Watch", - preview : "HTML Preview (Press Shift + ESC exit)", - fullscreen : "Fullscreen (Press ESC exit)", - clear : "Clear", - search : "Search", - help : "Help", - info : "About " + exports.title + // 工具栏各按钮的英语翻译 + // English translations for toolbar buttons + undo : "Undo(Ctrl+Z)", // 撤销 + redo : "Redo(Ctrl+Y)", // 重做 + bold : "Bold", // 粗体 + del : "Strikethrough", // 删除线 + italic : "Italic", // 斜体 + quote : "Block quote", // 块引用 + ucwords : "Words first letter convert to uppercase", // 单词首字母大写 + uppercase : "Selection text convert to uppercase", // 转换为大写 + lowercase : "Selection text convert to lowercase", // 转换为小写 + h1 : "Heading 1", // 标题1 + h2 : "Heading 2", // 标题2 + h3 : "Heading 3", // 标题3 + h4 : "Heading 4", // 标题4 + h5 : "Heading 5", // 标题5 + h6 : "Heading 6", // 标题6 + "list-ul" : "Unordered list", // 无序列表 + "list-ol" : "Ordered list", // 有序列表 + hr : "Horizontal rule", // 水平线 + link : "Link", // 链接 + "reference-link" : "Reference link", // 引用链接 + image : "Image", // 图片 + code : "Code inline", // 行内代码 + "preformatted-text" : "Preformatted text / Code block (Tab indent)", // 预格式化文本/代码块 + "code-block" : "Code block (Multi-languages)", // 代码块(多语言) + table : "Tables", // 表格 + datetime : "Datetime", // 日期时间 + emoji : "Emoji", // 表情符号 + "html-entities" : "HTML Entities", // HTML实体 + pagebreak : "Page break", // 分页符 + watch : "Unwatch", // 关闭实时预览 + unwatch : "Watch", // 开启实时预览 + preview : "HTML Preview (Press Shift + ESC exit)", // HTML预览 + fullscreen : "Fullscreen (Press ESC exit)", // 全屏 + clear : "Clear", // 清除 + search : "Search", // 搜索 + help : "Help", // 帮助 + info : "About " + exports.title // 关于信息 }, buttons : { - enter : "Enter", - cancel : "Cancel", - close : "Close" + // 对话框按钮文本 + // Dialog button texts + enter : "Enter", // 确定按钮 + cancel : "Cancel", // 取消按钮 + close : "Close" // 关闭按钮 }, dialog : { + // 各种对话框的英语翻译 + // English translations for various dialogs link : { - title : "Link", - url : "Address", - urlTitle : "Title", - urlEmpty : "Error: Please fill in the link address." + title : "Link", // 链接对话框标题 + url : "Address", // URL地址标签 + urlTitle : "Title", // 标题标签 + urlEmpty : "Error: Please fill in the link address." // URL为空时的错误提示 }, referenceLink : { - title : "Reference link", - name : "Name", - url : "Address", - urlId : "ID", - urlTitle : "Title", - nameEmpty: "Error: Reference name can't be empty.", - idEmpty : "Error: Please fill in reference link id.", - urlEmpty : "Error: Please fill in reference link url address." + title : "Reference link", // 引用链接对话框标题 + name : "Name", // 名称标签 + url : "Address", // URL地址标签 + urlId : "ID", // ID标签 + urlTitle : "Title", // 标题标签 + nameEmpty: "Error: Reference name can't be empty.", // 名称为空时的错误提示 + idEmpty : "Error: Please fill in reference link id.", // ID为空时的错误提示 + urlEmpty : "Error: Please fill in reference link url address." // URL为空时的错误提示 }, image : { - title : "Image", - url : "Address", - link : "Link", - alt : "Title", - uploadButton : "Upload", - imageURLEmpty : "Error: picture url address can't be empty.", - uploadFileEmpty : "Error: upload pictures cannot be empty!", - formatNotAllowed : "Error: only allows to upload pictures file, upload allowed image file format:" + title : "Image", // 图片对话框标题 + url : "Address", // URL地址标签 + link : "Link", // 链接标签 + alt : "Title", // 标题(alt属性)标签 + uploadButton : "Upload", // 上传按钮 + imageURLEmpty : "Error: picture url address can't be empty.", // 图片URL为空时的错误提示 + uploadFileEmpty : "Error: upload pictures cannot be empty!", // 上传文件为空时的错误提示 + formatNotAllowed : "Error: only allows to upload pictures file, upload allowed image file format:" // 文件格式不允许时的错误提示 }, preformattedText : { - title : "Preformatted text / Codes", - emptyAlert : "Error: Please fill in the Preformatted text or content of the codes.", - placeholder : "coding now...." + title : "Preformatted text / Codes", // 预格式化文本对话框标题 + emptyAlert : "Error: Please fill in the Preformatted text or content of the codes.", // 内容为空时的错误提示 + placeholder : "coding now...." // 占位符文本 }, codeBlock : { - title : "Code block", - selectLabel : "Languages: ", - selectDefaultText : "select a code language...", - otherLanguage : "Other languages", - unselectedLanguageAlert : "Error: Please select the code language.", - codeEmptyAlert : "Error: Please fill in the code content.", - placeholder : "coding now...." + title : "Code block", // 代码块对话框标题 + selectLabel : "Languages: ", // 语言选择标签 + selectDefaultText : "select a code language...", // 默认选择文本 + otherLanguage : "Other languages", // 其他语言选项 + unselectedLanguageAlert : "Error: Please select the code language.", // 未选择语言时的错误提示 + codeEmptyAlert : "Error: Please fill in the code content.", // 代码内容为空时的错误提示 + placeholder : "coding now...." // 占位符文本 }, htmlEntities : { - title : "HTML Entities" + title : "HTML Entities" // HTML实体对话框标题 }, help : { - title : "Help" + title : "Help" // 帮助对话框标题 } } }; + // 将语言配置导出 + // Export language configuration exports.defaults.lang = lang; }; + // 根据不同的模块加载方式导出语言包 + // Export language package according to different module loading methods // CommonJS/Node.js if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { diff --git a/src/collectedstatic/mdeditor/languages/es.js b/src/collectedstatic/mdeditor/languages/es.js index b6b6586..359af68 100644 --- a/src/collectedstatic/mdeditor/languages/es.js +++ b/src/collectedstatic/mdeditor/languages/es.js @@ -1,106 +1,120 @@ (function(){ + // 工厂函数,用于定义西班牙语语言包 + // Factory function to define Spanish language package var factory = function (exports) { + // 定义西班牙语语言配置对象 + // Define Spanish language configuration object var lang = { - name : "ex", - description : "Open source online Markdown editor.", - tocTitle : "Índice", + name : "ex", // 语言名称 - Language name + description : "Open source online Markdown editor.", // 描述 - Description + tocTitle : "Índice", // 目录标题 - Table of contents title toolbar : { - undo : "Deshacer (Ctrl+Z)", - redo : "Rehacer (Ctrl+Y)", - bold : "Bold", - del : "Tachado", - italic : "Cursiva", - quote : "Citar", - ucwords : "Primera letra de las en mayúsculas", - uppercase : "Convertir la selección a mayúsculas", - lowercase : "Convertir la selección a minúsculas", - h1 : "Título 1", - h2 : "Título 2", - h3 : "Título 3", - h4 : "Título 4", - h5 : "Título 5", - h6 : "Título 6", - "list-ul" : "Lista no ordenada", - "list-ol" : "Lista ordenada", - hr : "Línea horizontal", - link : "Enlace", - "reference-link" : "Referencia a enlace", - image : "Imagen", - code : "Código", - "preformatted-text" : "Texto preformateado / Bloque de código (Indentado por Tab)", - "code-block" : "Bloque de código (Multi-lenguaje)", - table : "Tables", - datetime : "Datetime", - emoji : "Emoji", - "html-entities" : "Entidades HTML", - pagebreak : "Salto de página", - watch : "Unwatch", - unwatch : "Watch", - preview : "Vista previa HTML (Shift + ESC para salir)", - fullscreen : "Pantalla completa (ESC para salir)", - clear : "Borrar", - search : "Buscar", - help : "Ayuda", - info : "Sobre " + exports.title + // 工具栏各按钮的西班牙语翻译 + // Spanish translations for toolbar buttons + undo : "Deshacer (Ctrl+Z)", // 撤销 + redo : "Rehacer (Ctrl+Y)", // 重做 + bold : "Bold", // 粗体 + del : "Tachado", // 删除线 + italic : "Cursiva", // 斜体 + quote : "Citar", // 引用 + ucwords : "Primera letra de las en mayúsculas", // 单词首字母大写 + uppercase : "Convertir la selección a mayúsculas", // 转换为大写 + lowercase : "Convertir la selección a minúsculas", // 转换为小写 + h1 : "Título 1", // 标题1 + h2 : "Título 2", // 标题2 + h3 : "Título 3", // 标题3 + h4 : "Título 4", // 标题4 + h5 : "Título 5", // 标题5 + h6 : "Título 6", // 标题6 + "list-ul" : "Lista no ordenada", // 无序列表 + "list-ol" : "Lista ordenada", // 有序列表 + hr : "Línea horizontal", // 水平线 + link : "Enlace", // 链接 + "reference-link" : "Referencia a enlace", // 引用链接 + image : "Imagen", // 图片 + code : "Código", // 代码 + "preformatted-text" : "Texto preformateado / Bloque de código (Indentado por Tab)", // 预格式化文本/代码块 + "code-block" : "Bloque de código (Multi-lenguaje)", // 代码块(多语言) + table : "Tables", // 表格 + datetime : "Datetime", // 日期时间 + emoji : "Emoji", // 表情符号 + "html-entities" : "Entidades HTML", // HTML实体 + pagebreak : "Salto de página", // 分页符 + watch : "Unwatch", // 关闭实时预览 + unwatch : "Watch", // 开启实时预览 + preview : "Vista previa HTML (Shift + ESC para salir)", // HTML预览 + fullscreen : "Pantalla completa (ESC para salir)", // 全屏 + clear : "Borrar", // 清除 + search : "Buscar", // 搜索 + help : "Ayuda", // 帮助 + info : "Sobre " + exports.title // 关于信息 }, buttons : { - enter : "Intro", - cancel : "Cancelar", - close : "Cerrar" + // 对话框按钮文本 + // Dialog button texts + enter : "Intro", // 确定按钮 + cancel : "Cancelar", // 取消按钮 + close : "Cerrar" // 关闭按钮 }, dialog : { + // 各种对话框的西班牙语翻译 + // Spanish translations for various dialogs link : { - title : "Enlace", - url : "Dirección", - urlTitle : "Título", - urlEmpty : "Error: Introduzca la dirección del enlace." + title : "Enlace", // 链接对话框标题 + url : "Dirección", // URL地址标签 + urlTitle : "Título", // 标题标签 + urlEmpty : "Error: Introduzca la dirección del enlace." // URL为空时的错误提示 }, referenceLink : { - title : "Referencia a enlace", - name : "Nombre", - url : "Dirección", - urlId : "ID", - urlTitle : "Título", - nameEmpty: "Error: El nombre no puede estar vacío.", - idEmpty : "Error: Introduzca un ID.", - urlEmpty : "Error: Introduzca una dirección URL." + title : "Referencia a enlace", // 引用链接对话框标题 + name : "Nombre", // 名称标签 + url : "Dirección", // URL地址标签 + urlId : "ID", // ID标签 + urlTitle : "Título", // 标题标签 + nameEmpty: "Error: El nombre no puede estar vacío.", // 名称为空时的错误提示 + idEmpty : "Error: Introduzca un ID.", // ID为空时的错误提示 + urlEmpty : "Error: Introduzca una dirección URL." // URL为空时的错误提示 }, image : { - title : "Imagen", - url : "Dirección", - link : "Enlace", - alt : "Título", - uploadButton : "Cargar", - imageURLEmpty : "Error: La dirección URL de la imagen no pueder estar vacia.", - uploadFileEmpty : "Error: upload pictures cannot be empty!", - formatNotAllowed : "Error: Sólo se pueden cargar ficheros de imagen, los formatos permitidos son:" + title : "Imagen", // 图片对话框标题 + url : "Dirección", // URL地址标签 + link : "Enlace", // 链接标签 + alt : "Título", // 标题(alt属性)标签 + uploadButton : "Cargar", // 上传按钮 + imageURLEmpty : "Error: La dirección URL de la imagen no pueder estar vacia.", // 图片URL为空时的错误提示 + uploadFileEmpty : "Error: upload pictures cannot be empty!", // 上传文件为空时的错误提示 + formatNotAllowed : "Error: Sólo se pueden cargar ficheros de imagen, los formatos permitidos son:" // 文件格式不允许时的错误提示 }, preformattedText : { - title : "Texto preformateado / Código", - emptyAlert : "Error: Introduzca el texto preformateado o el código.", - placeholder : "Código...." + title : "Texto preformateado / Código", // 预格式化文本对话框标题 + emptyAlert : "Error: Introduzca el texto preformateado o el código.", // 内容为空时的错误提示 + placeholder : "Código...." // 占位符文本 }, codeBlock : { - title : "Bloque de código", - selectLabel : "Lenguajes: ", - selectDefaultText : "Selecciona un lenguaje...", - otherLanguage : "Otros", - unselectedLanguageAlert : "Error: Selecciona un lenguaje.", - codeEmptyAlert : "Error: Introduce el código.", - placeholder : "Código...." + title : "Bloque de código", // 代码块对话框标题 + selectLabel : "Lenguajes: ", // 语言选择标签 + selectDefaultText : "Selecciona un lenguaje...", // 默认选择文本 + otherLanguage : "Otros", // 其他语言选项 + unselectedLanguageAlert : "Error: Selecciona un lenguaje.", // 未选择语言时的错误提示 + codeEmptyAlert : "Error: Introduce el código.", // 代码内容为空时的错误提示 + placeholder : "Código...." // 占位符文本 }, htmlEntities : { - title : "Entidades HTML" + title : "Entidades HTML" // HTML实体对话框标题 }, help : { - title : "Ayuda" + title : "Ayuda" // 帮助对话框标题 } } }; + // 将语言配置导出 + // Export language configuration exports.defaults.lang = lang; }; + // 根据不同的模块加载方式导出语言包 + // Export language package according to different module loading methods // CommonJS/Node.js if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { @@ -126,4 +140,4 @@ factory(window.editormd); } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/mdeditor/languages/pt_BR.js b/src/collectedstatic/mdeditor/languages/pt_BR.js index 727914f..f6f9e53 100644 --- a/src/collectedstatic/mdeditor/languages/pt_BR.js +++ b/src/collectedstatic/mdeditor/languages/pt_BR.js @@ -1,106 +1,120 @@ (function(){ + // 工厂函数,用于定义巴西葡萄牙语语言包 + // Factory function to define Brazilian Portuguese language package var factory = function (exports) { + // 定义巴西葡萄牙语语言配置对象 + // Define Brazilian Portuguese language configuration object var lang = { - name : "pt_BR", - description : "Open source online Markdown editor.", - tocTitle : "Índice", + name : "pt_BR", // 语言名称 - Language name + description : "Open source online Markdown editor.", // 描述 - Description + tocTitle : "Índice", // 目录标题 - Table of contents title toolbar : { - undo : "Desfazer(Ctrl+Z)", - redo : "Refazer(Ctrl+Y)", - bold : "Negrito", - del : "Tachado", - italic : "Itálico", - quote : "Bloco de Citação", - ucwords : "Palavras com a primeira letra em maiúscula", - uppercase : "Texto em maiúsculas", - lowercase : "Texto em minúsculas", - h1 : "Título 1", - h2 : "Título 2", - h3 : "Título 3", - h4 : "Título 4", - h5 : "Título 5", - h6 : "Título 6", - "list-ul" : "Lista não ordenada", - "list-ol" : "Lista ordenada", - hr : "Linha Horizontal", - link : "Link", - "reference-link" : "Link de referência", - image : "Imagem", - code : "Código embutído", - "preformatted-text" : "Texto pré-formatado / Bloco de Código (Identado por Tab)", - "code-block" : "Bloco de Código (Multi-linguagens)", - table : "Tabelas", - datetime : "Data/hora", - emoji : "Emoji", - "html-entities" : "Elemento de HTML", - pagebreak : "Quebra de página", - watch : "Não Ver", - unwatch : "Ver", - preview : "HTML Preview (Pressione Shift + ESC para sair)", - fullscreen : "Tela Cheia (Pressione ESC para sair)", - clear : "Limpar", - search : "Procurar", - help : "Ajuda", - info : "Sobre " + exports.title + // 工具栏各按钮的巴西葡萄牙语翻译 + // Brazilian Portuguese translations for toolbar buttons + undo : "Desfazer(Ctrl+Z)", // 撤销 + redo : "Refazer(Ctrl+Y)", // 重做 + bold : "Negrito", // 粗体 + del : "Tachado", // 删除线 + italic : "Itálico", // 斜体 + quote : "Bloco de Citação", // 块引用 + ucwords : "Palavras com a primeira letra em maiúscula", // 单词首字母大写 + uppercase : "Texto em maiúsculas", // 转换为大写 + lowercase : "Texto em minúsculas", // 转换为小写 + h1 : "Título 1", // 标题1 + h2 : "Título 2", // 标题2 + h3 : "Título 3", // 标题3 + h4 : "Título 4", // 标题4 + h5 : "Título 5", // 标题5 + h6 : "Título 6", // 标题6 + "list-ul" : "Lista não ordenada", // 无序列表 + "list-ol" : "Lista ordenada", // 有序列表 + hr : "Linha Horizontal", // 水平线 + link : "Link", // 链接 + "reference-link" : "Link de referência", // 引用链接 + image : "Imagem", // 图片 + code : "Código embutído", // 行内代码 + "preformatted-text" : "Texto pré-formatado / Bloco de Código (Identado por Tab)", // 预格式化文本/代码块 + "code-block" : "Bloco de Código (Multi-linguagens)", // 代码块(多语言) + table : "Tabelas", // 表格 + datetime : "Data/hora", // 日期时间 + emoji : "Emoji", // 表情符号 + "html-entities" : "Elemento de HTML", // HTML实体 + pagebreak : "Quebra de página", // 分页符 + watch : "Não Ver", // 关闭实时预览 + unwatch : "Ver", // 开启实时预览 + preview : "HTML Preview (Pressione Shift + ESC para sair)", // HTML预览 + fullscreen : "Tela Cheia (Pressione ESC para sair)", // 全屏 + clear : "Limpar", // 清除 + search : "Procurar", // 搜索 + help : "Ajuda", // 帮助 + info : "Sobre " + exports.title // 关于信息 }, buttons : { - enter : "OK", - cancel : "Cancelar", - close : "Fechar" + // 对话框按钮文本 + // Dialog button texts + enter : "OK", // 确定按钮 + cancel : "Cancelar", // 取消按钮 + close : "Fechar" // 关闭按钮 }, dialog : { + // 各种对话框的巴西葡萄牙语翻译 + // Brazilian Portuguese translations for various dialogs link : { - title : "Link", - url : "Endereço", - urlTitle : "Titulo", - urlEmpty : "Erro: Pro favor, preença o endereço do link." + title : "Link", // 链接对话框标题 + url : "Endereço", // URL地址标签 + urlTitle : "Titulo", // 标题标签 + urlEmpty : "Erro: Pro favor, preença o endereço do link." // URL为空时的错误提示 }, referenceLink : { - title : "Link de referência", - name : "Nome", - url : "Endereço", - urlId : "ID", - urlTitle : "Titulo", - nameEmpty: "Erro: Nome de referência não pode estar vazio.", - idEmpty : "Erro: Por favor preencha o link de refeência com id válido.", - urlEmpty : "Erro: Por favor preencha o link com uma url de referência correta." + title : "Link de referência", // 引用链接对话框标题 + name : "Nome", // 名称标签 + url : "Endereço", // URL地址标签 + urlId : "ID", // ID标签 + urlTitle : "Titulo", // 标题标签 + nameEmpty: "Erro: Nome de referência não pode estar vazio.", // 名称为空时的错误提示 + idEmpty : "Erro: Por favor preencha o link de refeência com id válido.", // ID为空时的错误提示 + urlEmpty : "Erro: Por favor preencha o link com uma url de referência correta." // URL为空时的错误提示 }, image : { - title : "Imagem", - url : "Endereço", - link : "Link", - alt : "Titulo", - uploadButton : "Envio", - imageURLEmpty : "Erro: Endereço da imagem não pode estar em branco.", - uploadFileEmpty : "Erro: É necessário enviar a imagem. Não pode estar vazio!", - formatNotAllowed : "Erro: Somente é possível enviar arquivos de figuras, Formatos permitidos:" + title : "Imagem", // 图片对话框标题 + url : "Endereço", // URL地址标签 + link : "Link", // 链接标签 + alt : "Titulo", // 标题(alt属性)标签 + uploadButton : "Envio", // 上传按钮 + imageURLEmpty : "Erro: Endereço da imagem não pode estar em branco.", // 图片URL为空时的错误提示 + uploadFileEmpty : "Erro: É necessário enviar a imagem. Não pode estar vazio!", // 上传文件为空时的错误提示 + formatNotAllowed : "Erro: Somente é possível enviar arquivos de figuras, Formatos permitidos:" // 文件格式不允许时的错误提示 }, preformattedText : { - title : "Texto pré-formatado / Código", - emptyAlert : "Erro: Por favor preencher aqui com seu texto pré formatado / código.", - placeholder : "codificando agora...." + title : "Texto pré-formatado / Código", // 预格式化文本对话框标题 + emptyAlert : "Erro: Por favor preencher aqui com seu texto pré formatado / código.", // 内容为空时的错误提示 + placeholder : "codificando agora...." // 占位符文本 }, codeBlock : { - title : "Bloco de Código", - selectLabel : "Linguagens: ", - selectDefaultText : "selecione o tipo de linguagem ...", - otherLanguage : "Outras linguagenss", - unselectedLanguageAlert : "Erro: Por favor selecione a linguagem do código.", - codeEmptyAlert : "Erro: Por favor selecione o conteúdo de código.", - placeholder : "codificando agora...." + title : "Bloco de Código", // 代码块对话框标题 + selectLabel : "Linguagens: ", // 语言选择标签 + selectDefaultText : "selecione o tipo de linguagem ...", // 默认选择文本 + otherLanguage : "Outras linguagenss", // 其他语言选项 + unselectedLanguageAlert : "Erro: Por favor selecione a linguagem do código.", // 未选择语言时的错误提示 + codeEmptyAlert : "Erro: Por favor selecione o conteúdo de código.", // 代码内容为空时的错误提示 + placeholder : "codificando agora...." // 占位符文本 }, htmlEntities : { - title : "Elementos HTML" + title : "Elementos HTML" // HTML实体对话框标题 }, help : { - title : "Ajuda" + title : "Ajuda" // 帮助对话框标题 } } }; + // 将语言配置导出 + // Export language configuration exports.defaults.lang = lang; }; + // 根据不同的模块加载方式导出语言包 + // Export language package according to different module loading methods // CommonJS/Node.js if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { @@ -126,4 +140,4 @@ factory(window.editormd); } -})(); +})(); \ No newline at end of file diff --git a/src/collectedstatic/pygments/default.css b/src/collectedstatic/pygments/default.css index 73e6e49..977ef5f 100644 --- a/src/collectedstatic/pygments/default.css +++ b/src/collectedstatic/pygments/default.css @@ -1,293 +1,352 @@ +/* 代码高亮样式 */ .codehilite .hll { background-color: #ffffcc } +/* 代码块背景 */ .codehilite { background: #ffffff; } +/* 注释 */ .codehilite .c { color: #177500 } -/* Comment */ +/* 注释 */ +/* Error */ .codehilite .err { color: #000000 } -/* Error */ +/* 错误 */ +/* Keyword */ .codehilite .k { color: #A90D91 } -/* Keyword */ +/* 关键字 */ +/* Literal */ .codehilite .l { color: #1C01CE } -/* Literal */ +/* 字面量 */ +/* Name */ .codehilite .n { color: #000000 } -/* Name */ +/* 名称 */ +/* Operator */ .codehilite .o { color: #000000 } -/* Operator */ +/* 操作符 */ +/* Comment.Hashbang */ .codehilite .ch { color: #177500 } -/* Comment.Hashbang */ +/* Hashbang注释 */ +/* Comment.Multiline */ .codehilite .cm { color: #177500 } -/* Comment.Multiline */ +/* 多行注释 */ +/* Comment.Preproc */ .codehilite .cp { color: #633820 } -/* Comment.Preproc */ +/* 预处理注释 */ +/* Comment.PreprocFile */ .codehilite .cpf { color: #177500 } -/* Comment.PreprocFile */ +/* 文件预处理注释 */ +/* Comment.Single */ .codehilite .c1 { color: #177500 } -/* Comment.Single */ +/* 单行注释 */ +/* Comment.Special */ .codehilite .cs { color: #177500 } -/* Comment.Special */ +/* 特殊注释 */ +/* Keyword.Constant */ .codehilite .kc { color: #A90D91 } -/* Keyword.Constant */ +/* 常量关键字 */ +/* Keyword.Declaration */ .codehilite .kd { color: #A90D91 } -/* Keyword.Declaration */ +/* 声明关键字 */ +/* Keyword.Namespace */ .codehilite .kn { color: #A90D91 } -/* Keyword.Namespace */ +/* 命名空间关键字 */ +/* Keyword.Pseudo */ .codehilite .kp { color: #A90D91 } -/* Keyword.Pseudo */ +/* 伪关键字 */ +/* Keyword.Reserved */ .codehilite .kr { color: #A90D91 } -/* Keyword.Reserved */ +/* 保留关键字 */ +/* Keyword.Type */ .codehilite .kt { color: #A90D91 } -/* Keyword.Type */ +/* 类型关键字 */ +/* Literal.Date */ .codehilite .ld { color: #1C01CE } -/* Literal.Date */ +/* 日期字面量 */ +/* Literal.Number */ .codehilite .m { color: #1C01CE } -/* Literal.Number */ +/* 数字字面量 */ +/* Literal.String */ .codehilite .s { color: #C41A16 } -/* Literal.String */ +/* 字符串字面量 */ +/* Name.Attribute */ .codehilite .na { color: #836C28 } -/* Name.Attribute */ +/* 属性名称 */ +/* Name.Builtin */ .codehilite .nb { color: #A90D91 } -/* Name.Builtin */ +/* 内置名称 */ +/* Name.Class */ .codehilite .nc { color: #3F6E75 } -/* Name.Class */ +/* 类名 */ +/* Name.Constant */ .codehilite .no { color: #000000 } -/* Name.Constant */ +/* 常量名称 */ +/* Name.Decorator */ .codehilite .nd { color: #000000 } -/* Name.Decorator */ +/* 装饰器名称 */ +/* Name.Entity */ .codehilite .ni { color: #000000 } -/* Name.Entity */ +/* 实体名称 */ +/* Name.Exception */ .codehilite .ne { color: #000000 } -/* Name.Exception */ +/* 异常名称 */ +/* Name.Function */ .codehilite .nf { color: #000000 } -/* Name.Function */ +/* 函数名称 */ +/* Name.Label */ .codehilite .nl { color: #000000 } -/* Name.Label */ +/* 标签名称 */ +/* Name.Namespace */ .codehilite .nn { color: #000000 } -/* Name.Namespace */ +/* 命名空间名称 */ +/* Name.Other */ .codehilite .nx { color: #000000 } -/* Name.Other */ +/* 其他名称 */ +/* Name.Property */ .codehilite .py { color: #000000 } -/* Name.Property */ +/* 属性名称 */ +/* Name.Tag */ .codehilite .nt { color: #000000 } -/* Name.Tag */ +/* 标签名称 */ +/* Name.Variable */ .codehilite .nv { color: #000000 } -/* Name.Variable */ +/* 变量名称 */ +/* Operator.Word */ .codehilite .ow { color: #000000 } -/* Operator.Word */ +/* 操作符单词 */ +/* Literal.Number.Bin */ .codehilite .mb { color: #1C01CE } -/* Literal.Number.Bin */ +/* 二进制数字 */ +/* Literal.Number.Float */ .codehilite .mf { color: #1C01CE } -/* Literal.Number.Float */ +/* 浮点数 */ +/* Literal.Number.Hex */ .codehilite .mh { color: #1C01CE } -/* Literal.Number.Hex */ +/* 十六进制数 */ +/* Literal.Number.Integer */ .codehilite .mi { color: #1C01CE } -/* Literal.Number.Integer */ +/* 整数 */ +/* Literal.Number.Oct */ .codehilite .mo { color: #1C01CE } -/* Literal.Number.Oct */ +/* 八进制数 */ +/* Literal.String.Backtick */ .codehilite .sb { color: #C41A16 } -/* Literal.String.Backtick */ +/* 反引号字符串 */ +/* Literal.String.Char */ .codehilite .sc { color: #2300CE } -/* Literal.String.Char */ +/* 字符 */ +/* Literal.String.Doc */ .codehilite .sd { color: #C41A16 } -/* Literal.String.Doc */ +/* 文档字符串 */ +/* Literal.String.Double */ .codehilite .s2 { color: #C41A16 } -/* Literal.String.Double */ +/* 双引号字符串 */ +/* Literal.String.Escape */ .codehilite .se { color: #C41A16 } -/* Literal.String.Escape */ +/* 转义字符串 */ +/* Literal.String.Heredoc */ .codehilite .sh { color: #C41A16 } -/* Literal.String.Heredoc */ +/* Heredoc字符串 */ +/* Literal.String.Interpol */ .codehilite .si { color: #C41A16 } -/* Literal.String.Interpol */ +/* 插值字符串 */ +/* Literal.String.Other */ .codehilite .sx { color: #C41A16 } -/* Literal.String.Other */ +/* 其他字符串 */ +/* Literal.String.Regex */ .codehilite .sr { color: #C41A16 } -/* Literal.String.Regex */ +/* 正则表达式 */ +/* Literal.String.Single */ .codehilite .s1 { color: #C41A16 } -/* Literal.String.Single */ +/* 单引号字符串 */ +/* Literal.String.Symbol */ .codehilite .ss { color: #C41A16 } -/* Literal.String.Symbol */ +/* 符号 */ +/* Name.Builtin.Pseudo */ .codehilite .bp { color: #5B269A } -/* Name.Builtin.Pseudo */ +/* 伪内置名称 */ +/* Name.Variable.Class */ .codehilite .vc { color: #000000 } -/* Name.Variable.Class */ +/* 类变量 */ +/* Name.Variable.Global */ .codehilite .vg { color: #000000 } -/* Name.Variable.Global */ +/* 全局变量 */ +/* Name.Variable.Instance */ .codehilite .vi { color: #000000 } -/* Name.Variable.Instance */ +/* 实例变量 */ +/* Literal.Number.Integer.Long */ .codehilite .il { color: #1C01CE } -/* Literal.Number.Integer.Long */ \ No newline at end of file +/* 长整数 */ \ No newline at end of file diff --git a/src/comments/admin.py b/src/comments/admin.py index a814f3f..0504144 100644 --- a/src/comments/admin.py +++ b/src/comments/admin.py @@ -5,19 +5,41 @@ from django.utils.translation import gettext_lazy as _ def disable_commentstatus(modeladmin, request, queryset): + """ + 批量操作函数:禁用选中的评论 + + Args: + modeladmin: 模型管理对象 + request: HTTP请求对象 + queryset: 选中的评论查询集 + """ queryset.update(is_enable=False) def enable_commentstatus(modeladmin, request, queryset): + """ + 批量操作函数:启用选中的评论 + + Args: + modeladmin: 模型管理对象 + request: HTTP请求对象 + queryset: 选中的评论查询集 + """ queryset.update(is_enable=True) +# 设置批量操作的显示名称 disable_commentstatus.short_description = _('Disable comments') enable_commentstatus.short_description = _('Enable comments') class CommentAdmin(admin.ModelAdmin): + """ + 评论模型在Django管理后台的配置类 + """ + # 每页显示的评论数量 list_per_page = 20 + # 后台列表页显示的字段 list_display = ( 'id', 'body', @@ -25,12 +47,25 @@ class CommentAdmin(admin.ModelAdmin): 'link_to_article', 'is_enable', 'creation_time') + # 可点击进入详情页的字段 list_display_links = ('id', 'body', 'is_enable') + # 右侧过滤器字段 list_filter = ('is_enable',) + # 后台表单中隐藏的字段 exclude = ('creation_time', 'last_modify_time') + # 注册批量操作函数 actions = [disable_commentstatus, enable_commentstatus] def link_to_userinfo(self, obj): + """ + 在列表页中显示作者信息的链接 + + Args: + obj (Comment): 评论对象 + + Returns: + str: HTML格式的链接字符串 + """ info = (obj.author._meta.app_label, obj.author._meta.model_name) link = reverse('admin:%s_%s_change' % info, args=(obj.author.id,)) return format_html( @@ -38,10 +73,20 @@ class CommentAdmin(admin.ModelAdmin): (link, obj.author.nickname if obj.author.nickname else obj.author.email)) def link_to_article(self, obj): + """ + 在列表页中显示所属文章的链接 + + Args: + obj (Comment): 评论对象 + + Returns: + str: HTML格式的链接字符串 + """ info = (obj.article._meta.app_label, obj.article._meta.model_name) link = reverse('admin:%s_%s_change' % info, args=(obj.article.id,)) return format_html( u'%s' % (link, obj.article.title)) + # 设置字段显示名称 link_to_userinfo.short_description = _('User') - link_to_article.short_description = _('Article') + link_to_article.short_description = _('Article') \ No newline at end of file diff --git a/src/comments/apps.py b/src/comments/apps.py index ff01b77..aba245a 100644 --- a/src/comments/apps.py +++ b/src/comments/apps.py @@ -2,4 +2,9 @@ from django.apps import AppConfig class CommentsConfig(AppConfig): - name = 'comments' + """ + 评论应用配置类 + 继承自Django的AppConfig类 + """ + # 应用名称,必须与应用目录名一致 + name = 'comments' \ No newline at end of file diff --git a/src/comments/forms.py b/src/comments/forms.py index e83737d..a93a8c0 100644 --- a/src/comments/forms.py +++ b/src/comments/forms.py @@ -5,9 +5,17 @@ from .models import Comment class CommentForm(ModelForm): + """ + 评论表单类 + 用于处理用户提交的评论数据 + 继承自ModelForm,与Comment模型关联 + """ + # 父评论ID隐藏字段,用于处理评论回复功能,可选 parent_comment_id = forms.IntegerField( widget=forms.HiddenInput, required=False) class Meta: + # 指定关联的模型 model = Comment - fields = ['body'] + # 指定表单包含的字段,只包含body字段 + fields = ['body'] \ No newline at end of file diff --git a/src/comments/migrations/0001_initial.py b/src/comments/migrations/0001_initial.py index 61d1e53..89a0d3d 100644 --- a/src/comments/migrations/0001_initial.py +++ b/src/comments/migrations/0001_initial.py @@ -1,4 +1,5 @@ # Generated by Django 4.1.7 on 2023-03-02 07:14 +# 这是一个Django迁移文件,用于创建评论(Comment)模型的初始数据库表结构 from django.conf import settings from django.db import migrations, models @@ -7,32 +8,46 @@ import django.utils.timezone class Migration(migrations.Migration): - + # initial = True 表示这是一个初始迁移文件 initial = True + # dependencies 列表定义了此迁移依赖的其他迁移 + # 'blog.0001_initial' 表示依赖blog应用的0001_initial迁移 + # AUTH_USER_MODEL 表示依赖用户模型的迁移 dependencies = [ ('blog', '0001_initial'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] + # operations 包含了实际要执行的数据库操作 operations = [ + # 创建Comment模型对应的数据库表 migrations.CreateModel( - name='Comment', + name='Comment', # 模型名称 fields=[ + # 主键字段,自动创建 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + # 评论正文,最大长度300字符 ('body', models.TextField(max_length=300, verbose_name='正文')), + # 创建时间,默认为当前时间 ('created_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='创建时间')), + # 最后修改时间,默认为当前时间 ('last_mod_time', models.DateTimeField(default=django.utils.timezone.now, verbose_name='修改时间')), + # 是否显示该评论,默认为True(显示) ('is_enable', models.BooleanField(default=True, verbose_name='是否显示')), + # 外键关联到blog应用的Article模型,表示评论所属的文章 ('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.article', verbose_name='文章')), + # 外键关联到用户模型,表示评论的作者 ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='作者')), + # 外键关联到自身的Comment模型,表示上级评论(用于实现评论回复功能) ('parent_comment', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comments.comment', verbose_name='上级评论')), ], + # 模型的元数据选项 options={ - 'verbose_name': '评论', - 'verbose_name_plural': '评论', - 'ordering': ['-id'], - 'get_latest_by': 'id', + 'verbose_name': '评论', # 单数形式的可读名称 + 'verbose_name_plural': '评论', # 复数形式的可读名称 + 'ordering': ['-id'], # 默认排序方式,按id倒序排列 + 'get_latest_by': 'id', # 用于获取最新对象的字段 }, ), - ] + ] \ No newline at end of file diff --git a/src/comments/migrations/0002_alter_comment_is_enable.py b/src/comments/migrations/0002_alter_comment_is_enable.py index 17c44db..8d26e1a 100644 --- a/src/comments/migrations/0002_alter_comment_is_enable.py +++ b/src/comments/migrations/0002_alter_comment_is_enable.py @@ -1,18 +1,22 @@ # Generated by Django 4.1.7 on 2023-04-24 13:48 +# 这是一个Django迁移文件,用于修改Comment模型的is_enable字段默认值 from django.db import migrations, models class Migration(migrations.Migration): - + # 依赖的迁移文件,表示此迁移必须在0001_initial.py之后执行 dependencies = [ ('comments', '0001_initial'), ] + # operations 包含了实际要执行的数据库操作 operations = [ + # 修改Comment模型的is_enable字段 migrations.AlterField( - model_name='comment', - name='is_enable', + model_name='comment', # 指定模型名称 + name='is_enable', # 指定字段名称 + # 将is_enable字段的默认值从True改为False field=models.BooleanField(default=False, verbose_name='是否显示'), ), - ] + ] \ No newline at end of file diff --git a/src/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py b/src/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py index a1ca970..06e23a1 100644 --- a/src/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py +++ b/src/comments/migrations/0003_alter_comment_options_remove_comment_created_time_and_more.py @@ -1,4 +1,9 @@ # Generated by Django 4.2.5 on 2023-09-06 13:13 +# 这是一个Django迁移文件,用于对Comment模型进行多项修改: +# 1. 修改模型选项 +# 2. 删除旧的时间字段 +# 3. 添加新的时间字段 +# 4. 修改字段的verbose_name为英文 from django.conf import settings from django.db import migrations, models @@ -7,54 +12,69 @@ import django.utils.timezone class Migration(migrations.Migration): - + # 依赖的迁移文件列表,当前迁移必须在这些迁移之后执行 dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('blog', '0005_alter_article_options_alter_category_options_and_more'), ('comments', '0002_alter_comment_is_enable'), ] + # operations 包含了实际要执行的数据库操作列表 operations = [ + # 修改Comment模型的选项设置 migrations.AlterModelOptions( - name='comment', - options={'get_latest_by': 'id', 'ordering': ['-id'], 'verbose_name': 'comment', 'verbose_name_plural': 'comment'}, + name='comment', # 指定模型名称 + options={ + 'get_latest_by': 'id', # 用于获取最新对象的字段 + 'ordering': ['-id'], # 默认排序方式,按id倒序排列 + 'verbose_name': 'comment', # 单数形式的可读名称(已改为英文) + 'verbose_name_plural': 'comment' # 复数形式的可读名称(已改为英文) + }, ), + # 删除Comment模型中的created_time字段 migrations.RemoveField( model_name='comment', name='created_time', ), + # 删除Comment模型中的last_mod_time字段 migrations.RemoveField( model_name='comment', name='last_mod_time', ), + # 添加新的creation_time字段,用于记录创建时间 migrations.AddField( model_name='comment', name='creation_time', field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'), ), + # 添加新的last_modify_time字段,用于记录最后修改时间 migrations.AddField( model_name='comment', name='last_modify_time', field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'), ), + # 修改article外键字段的verbose_name为英文 migrations.AlterField( model_name='comment', name='article', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.article', verbose_name='article'), ), + # 修改author外键字段的verbose_name为英文 migrations.AlterField( model_name='comment', name='author', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='author'), ), + # 修改is_enable字段的verbose_name为英文 migrations.AlterField( model_name='comment', name='is_enable', field=models.BooleanField(default=False, verbose_name='enable'), ), + # 修改parent_comment外键字段的verbose_name为英文 migrations.AlterField( model_name='comment', name='parent_comment', field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comments.comment', verbose_name='parent comment'), ), - ] + ] \ No newline at end of file diff --git a/src/comments/models.py b/src/comments/models.py index 7c3bbc8..c2c3749 100644 --- a/src/comments/models.py +++ b/src/comments/models.py @@ -9,31 +9,46 @@ from blog.models import Article # Create your models here. class Comment(models.Model): + """ + 评论模型类 + 用于存储用户对文章的评论信息 + """ + # 评论正文,最大长度300字符 body = models.TextField('正文', max_length=300) + # 创建时间,默认为当前时间 creation_time = models.DateTimeField(_('creation time'), default=now) + # 最后修改时间,默认为当前时间 last_modify_time = models.DateTimeField(_('last modify time'), default=now) + # 评论作者,外键关联到用户模型 author = models.ForeignKey( settings.AUTH_USER_MODEL, verbose_name=_('author'), on_delete=models.CASCADE) + # 所属文章,外键关联到文章模型 article = models.ForeignKey( Article, verbose_name=_('article'), on_delete=models.CASCADE) + # 父评论,用于实现评论回复功能,可以为空 parent_comment = models.ForeignKey( 'self', verbose_name=_('parent comment'), blank=True, null=True, on_delete=models.CASCADE) + # 是否启用(显示)该评论,默认为False(需要审核) is_enable = models.BooleanField(_('enable'), default=False, blank=False, null=False) class Meta: - ordering = ['-id'] - verbose_name = _('comment') - verbose_name_plural = verbose_name - get_latest_by = 'id' + # 模型元数据选项 + ordering = ['-id'] # 默认按ID倒序排列 + verbose_name = _('comment') # 单数形式的可读名称 + verbose_name_plural = verbose_name # 复数形式的可读名称 + get_latest_by = 'id' # 用于获取最新对象的字段 def __str__(self): - return self.body + """ + 返回评论的字符串表示形式(返回评论正文) + """ + return self.body \ No newline at end of file diff --git a/src/comments/templatetags/comments_tags.py b/src/comments/templatetags/comments_tags.py index fde02b4..131b304 100644 --- a/src/comments/templatetags/comments_tags.py +++ b/src/comments/templatetags/comments_tags.py @@ -1,19 +1,37 @@ from django import template +# 注册模板标签 register = template.Library() @register.simple_tag def parse_commenttree(commentlist, comment): - """获得当前评论子评论的列表 - 用法: {% parse_commenttree article_comments comment as childcomments %} + """ + 解析获取当前评论的所有子评论(回复) + + 用法: {% parse_commenttree article_comments comment as childcomments %} + + Args: + commentlist: 评论列表查询集 + comment: 父评论对象 + + Returns: + list: 包含所有子评论的列表 """ datas = [] def parse(c): + """ + 递归解析评论的子评论 + + Args: + c: 当前评论对象 + """ + # 筛选出当前评论的已启用子评论 childs = commentlist.filter(parent_comment=c, is_enable=True) for child in childs: datas.append(child) + # 递归处理子评论的子评论 parse(child) parse(comment) @@ -22,9 +40,19 @@ def parse_commenttree(commentlist, comment): @register.inclusion_tag('comments/tags/comment_item.html') def show_comment_item(comment, ischild): - """评论""" + """ + 显示单个评论项的 inclusion tag + + Args: + comment: 评论对象 + ischild: 是否为子评论(回复) + + Returns: + dict: 传递给模板的上下文数据 + """ + # 设置评论显示深度,子评论深度为1,父评论深度为2 depth = 1 if ischild else 2 return { 'comment_item': comment, 'depth': depth - } + } \ No newline at end of file diff --git a/src/comments/tests.py b/src/comments/tests.py index 2a7f55f..b8f9c82 100644 --- a/src/comments/tests.py +++ b/src/comments/tests.py @@ -11,7 +11,16 @@ from djangoblog.utils import get_max_articleid_commentid # Create your tests here. class CommentsTest(TransactionTestCase): + """ + 评论功能测试类 + 使用TransactionTestCase以确保测试方法之间数据库事务的隔离性 + """ + def setUp(self): + """ + 测试前的准备工作 + 初始化测试客户端、请求工厂和创建测试用户 + """ self.client = Client() self.factory = RequestFactory() from blog.models import BlogSettings @@ -25,18 +34,31 @@ class CommentsTest(TransactionTestCase): password="liangliangyy1") def update_article_comment_status(self, article): + """ + 更新文章的评论状态为启用 + + Args: + article (Article): 文章对象 + """ comments = article.comment_set.all() for comment in comments: comment.is_enable = True comment.save() def test_validate_comment(self): + """ + 验证评论功能的测试方法 + 测试评论提交、显示和回复等功能 + """ + # 用户登录 self.client.login(username='liangliangyy1', password='liangliangyy1') + # 创建测试分类 category = Category() category.name = "categoryccc" category.save() + # 创建测试文章 article = Article() article.title = "nicetitleccc" article.body = "nicecontentccc" @@ -46,23 +68,30 @@ class CommentsTest(TransactionTestCase): article.status = 'p' article.save() + # 获取评论提交URL comment_url = reverse( 'comments:postcomment', kwargs={ 'article_id': article.id}) + # 提交第一条评论 response = self.client.post(comment_url, { 'body': '123ffffffffff' }) + # 检查重定向响应 self.assertEqual(response.status_code, 302) + # 获取更新后的文章对象,检查评论列表为空(因为评论需要审核) article = Article.objects.get(pk=article.pk) self.assertEqual(len(article.comment_list()), 0) + # 更新评论状态为启用 self.update_article_comment_status(article) + # 检查评论列表长度为1 self.assertEqual(len(article.comment_list()), 1) + # 提交第二条评论 response = self.client.post(comment_url, { 'body': '123ffffffffff', @@ -70,11 +99,14 @@ class CommentsTest(TransactionTestCase): self.assertEqual(response.status_code, 302) + # 更新评论状态并检查评论数量 article = Article.objects.get(pk=article.pk) self.update_article_comment_status(article) self.assertEqual(len(article.comment_list()), 2) + # 获取第一条评论ID作为父评论ID parent_comment_id = article.comment_list()[0].id + # 提交回复评论(带格式的评论内容) response = self.client.post(comment_url, { 'body': ''' @@ -96,14 +128,21 @@ class CommentsTest(TransactionTestCase): self.assertEqual(response.status_code, 302) self.update_article_comment_status(article) article = Article.objects.get(pk=article.pk) + # 检查评论总数为3(2条普通评论+1条回复评论) self.assertEqual(len(article.comment_list()), 3) + # 获取父评论对象 comment = Comment.objects.get(id=parent_comment_id) + # 解析评论树结构 tree = parse_commenttree(article.comment_list(), comment) + # 检查回复评论数量为1 self.assertEqual(len(tree), 1) + # 测试显示评论项功能 data = show_comment_item(comment, True) self.assertIsNotNone(data) + # 测试获取最大文章ID和评论ID功能 s = get_max_articleid_commentid() self.assertIsNotNone(s) + # 测试发送评论邮件功能 from comments.utils import send_comment_email - send_comment_email(comment) + send_comment_email(comment) \ No newline at end of file diff --git a/src/comments/urls.py b/src/comments/urls.py index 7df3fab..749eb4f 100644 --- a/src/comments/urls.py +++ b/src/comments/urls.py @@ -2,10 +2,13 @@ from django.urls import path from . import views +# 定义命名空间,用于区分不同应用的URL名称 app_name = "comments" urlpatterns = [ + # 评论提交URL + # 使用正则表达式捕获文章ID作为参数传递给视图函数 path( 'article//postcomment', views.CommentPostView.as_view(), name='postcomment'), -] +] \ No newline at end of file diff --git a/src/comments/utils.py b/src/comments/utils.py index f01dba7..0e58fc1 100644 --- a/src/comments/utils.py +++ b/src/comments/utils.py @@ -9,9 +9,23 @@ logger = logging.getLogger(__name__) def send_comment_email(comment): + """ + 发送评论相关邮件通知 + + 当用户发表评论后,系统会发送邮件通知: + 1. 给评论作者发送感谢邮件 + 2. 如果是回复评论,则给被回复的评论作者发送通知邮件 + + Args: + comment (Comment): 评论对象 + """ + # 获取当前站点域名 site = get_current_site().domain + # 邮件主题 subject = _('Thanks for your comment') + # 构造文章链接 article_url = f"https://{site}{comment.article.get_absolute_url()}" + # 邮件内容 - 给评论作者的感谢邮件 html_content = _("""

    Thank you very much for your comments on this site

    You can visit %(article_title)s to review your comments, @@ -19,9 +33,12 @@ def send_comment_email(comment):
    If the link above cannot be opened, please copy this link to your browser. %(article_url)s""") % {'article_url': article_url, 'article_title': comment.article.title} + # 获取评论作者邮箱 tomail = comment.author.email + # 发送邮件 send_email([tomail], subject, html_content) try: + # 如果是回复评论,给被回复的评论作者发送通知邮件 if comment.parent_comment: html_content = _("""Your comment on %(article_title)s
    has received a reply.
    %(comment_body)s @@ -32,7 +49,10 @@ def send_comment_email(comment): %(article_url)s """) % {'article_url': article_url, 'article_title': comment.article.title, 'comment_body': comment.parent_comment.body} + # 获取被回复评论的作者邮箱 tomail = comment.parent_comment.author.email + # 发送邮件通知 send_email([tomail], subject, html_content) except Exception as e: - logger.error(e) + # 记录异常日志 + logger.error(e) \ No newline at end of file diff --git a/src/comments/views.py b/src/comments/views.py index ad9b2b9..09f0d63 100644 --- a/src/comments/views.py +++ b/src/comments/views.py @@ -13,51 +13,104 @@ from .models import Comment class CommentPostView(FormView): + """ + 处理评论提交的视图类 + 继承自FormView,用于处理基于表单的评论提交 + """ + # 指定使用的表单类 form_class = CommentForm + # 指定模板名称 template_name = 'blog/article_detail.html' @method_decorator(csrf_protect) def dispatch(self, *args, **kwargs): + """ + 视图函数调度方法,添加CSRF保护装饰器 + """ return super(CommentPostView, self).dispatch(*args, **kwargs) def get(self, request, *args, **kwargs): + """ + 处理GET请求,重定向到文章详情页的评论部分 + + Args: + request: HTTP请求对象 + + Returns: + HttpResponseRedirect: 重定向响应 + """ + # 从URL参数中获取文章ID article_id = self.kwargs['article_id'] + # 获取文章对象,如果不存在则返回404 article = get_object_or_404(Article, pk=article_id) + # 获取文章的绝对URL url = article.get_absolute_url() + # 重定向到文章详情页的评论部分 return HttpResponseRedirect(url + "#comments") def form_invalid(self, form): + """ + 处理表单验证失败的情况 + + Args: + form: 验证失败的表单对象 + + Returns: + TemplateResponse: 渲染模板的响应 + """ + # 获取文章ID和文章对象 article_id = self.kwargs['article_id'] article = get_object_or_404(Article, pk=article_id) + # 重新渲染页面并显示错误信息 return self.render_to_response({ 'form': form, 'article': article }) def form_valid(self, form): - """提交的数据验证合法后的逻辑""" + """ + 提交的数据验证合法后的逻辑处理 + + Args: + form: 验证通过的表单对象 + + Returns: + HttpResponseRedirect: 重定向响应 + """ + # 获取当前登录用户 user = self.request.user + # 获取作者对象 author = BlogUser.objects.get(pk=user.pk) + # 获取文章ID和文章对象 article_id = self.kwargs['article_id'] article = get_object_or_404(Article, pk=article_id) + # 检查文章是否关闭了评论功能 if article.comment_status == 'c' or article.status == 'c': raise ValidationError("该文章评论已关闭.") + # 保存表单数据但不提交到数据库 comment = form.save(False) + # 关联评论与文章 comment.article = article + # 获取博客设置 from djangoblog.utils import get_blog_setting settings = get_blog_setting() + # 根据设置决定是否需要审核评论 if not settings.comment_need_review: comment.is_enable = True + # 关联评论与作者 comment.author = author + # 处理评论回复逻辑 if form.cleaned_data['parent_comment_id']: parent_comment = Comment.objects.get( pk=form.cleaned_data['parent_comment_id']) comment.parent_comment = parent_comment + # 保存评论到数据库 comment.save(True) + # 重定向到评论位置锚点 return HttpResponseRedirect( "%s#div-comment-%d" % - (article.get_absolute_url(), comment.pk)) + (article.get_absolute_url(), comment.pk)) \ No newline at end of file