forked from p3mk6vbs7/Django
Compare commits
59 Commits
Binary file not shown.
@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="feebdecb-aab4-468a-89d2-02ab184d6524" name="更改" comment="注释" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
||||
<map>
|
||||
<entry key="$PROJECT_DIR$" value="gjw_branch" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"customColor": "",
|
||||
"associatedIndex": 1
|
||||
}</component>
|
||||
<component name="ProjectId" id="33xBFgI9uhuAj9lNSHkgcMEmGEr" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"RunOnceActivity.OpenDjangoStructureViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"git-widget-placeholder": "master",
|
||||
"last_opened_file_path": "C:/Users/35500/Desktop/软件工程与方法学/django",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RunManager">
|
||||
<configuration name="django" type="Python.DjangoServer" factoryName="Django server">
|
||||
<module name="django" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="" />
|
||||
<option name="IS_MODULE_SDK" value="false" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="launchJavascriptDebuger" value="false" />
|
||||
<option name="port" value="8000" />
|
||||
<option name="host" value="" />
|
||||
<option name="additionalOptions" value="" />
|
||||
<option name="browserUrl" value="" />
|
||||
<option name="runTestServer" value="false" />
|
||||
<option name="runNoReload" value="false" />
|
||||
<option name="useCustomRunCommand" value="false" />
|
||||
<option name="customRunCommand" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-js-predefined-d6986cc7102b-b598e85cdad2-JavaScript-PY-252.25557.178" />
|
||||
<option value="bundled-python-sdk-ce6832f46686-7b97d883f26b-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-252.25557.178" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="默认任务">
|
||||
<changelist id="feebdecb-aab4-468a-89d2-02ab184d6524" name="更改" comment="" />
|
||||
<created>1760248745025</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1760248745025</updated>
|
||||
<workItem from="1760248747064" duration="34000" />
|
||||
<workItem from="1760248891758" duration="6962000" />
|
||||
<workItem from="1760271313858" duration="27000" />
|
||||
<workItem from="1760271342012" duration="835000" />
|
||||
<workItem from="1760851293582" duration="1237000" />
|
||||
<workItem from="1760852569906" duration="605000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
<option name="TAB_STATES">
|
||||
<map>
|
||||
<entry key="MAIN">
|
||||
<value>
|
||||
<State />
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -1 +0,0 @@
|
||||
Subproject commit 51c0763b7938a4b2616c068e850998ad2b00973e
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1 +0,0 @@
|
||||
Subproject commit 51c0763b7938a4b2616c068e850998ad2b00973e
|
||||
@ -1,9 +0,0 @@
|
||||
.button {
|
||||
border: none;
|
||||
padding: 4px 80px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
margin: 4px 2px;
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
let wait = 60;
|
||||
|
||||
function time(o) {
|
||||
if (wait == 0) {
|
||||
o.removeAttribute("disabled");
|
||||
o.value = "获取验证码";
|
||||
wait = 60
|
||||
return false
|
||||
} else {
|
||||
o.setAttribute("disabled", true);
|
||||
o.value = "重新发送(" + wait + ")";
|
||||
wait--;
|
||||
setTimeout(function () {
|
||||
time(o)
|
||||
},
|
||||
1000)
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("btn").onclick = function () {
|
||||
let id_email = $("#id_email")
|
||||
let token = $("*[name='csrfmiddlewaretoken']").val()
|
||||
let ts = this
|
||||
let myErr = $("#myErr")
|
||||
$.ajax(
|
||||
{
|
||||
url: "/forget_password_code/",
|
||||
type: "POST",
|
||||
data: {
|
||||
"email": id_email.val(),
|
||||
"csrfmiddlewaretoken": token
|
||||
},
|
||||
success: function (result) {
|
||||
if (result != "ok") {
|
||||
myErr.remove()
|
||||
id_email.after("<ul className='errorlist' id='myErr'><li>" + result + "</li></ul>")
|
||||
return
|
||||
}
|
||||
myErr.remove()
|
||||
time(ts)
|
||||
},
|
||||
error: function (e) {
|
||||
alert("发送失败,请重试")
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,13 +0,0 @@
|
||||
/*!
|
||||
* IE10 viewport hack for Surface/desktop Windows 8 bug
|
||||
* Copyright 2014-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
/*
|
||||
* See the Getting Started docs for more information:
|
||||
* http://getbootstrap.com/getting-started/#support-ie10-width
|
||||
*/
|
||||
@-ms-viewport { width: device-width; }
|
||||
@-o-viewport { width: device-width; }
|
||||
@viewport { width: device-width; }
|
||||
@ -1,58 +0,0 @@
|
||||
body {
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.form-signin {
|
||||
max-width: 330px;
|
||||
padding: 15px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.form-signin-heading {
|
||||
margin: 0 0 15px;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
color: #555;
|
||||
}
|
||||
.form-signin .checkbox {
|
||||
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;
|
||||
}
|
||||
.form-signin .form-control:focus {
|
||||
z-index: 2;
|
||||
}
|
||||
.form-signin input[type="email"] {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.form-signin input[type="password"] {
|
||||
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);
|
||||
}
|
||||
.card-signin {
|
||||
width: 354px;
|
||||
padding: 40px;
|
||||
}
|
||||
.card-signin .profile-img {
|
||||
display: block;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
margin: 0 auto 10px;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 221 B |
@ -1,51 +0,0 @@
|
||||
// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
|
||||
// IT'S JUST JUNK FOR OUR DOCS!
|
||||
// ++++++++++++++++++++++++++++++++++++++++++
|
||||
/*!
|
||||
* Copyright 2014-2015 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
|
||||
* details, see https://creativecommons.org/licenses/by/3.0/.
|
||||
*/
|
||||
// Intended to prevent false-positive bug reports about Bootstrap not working properly in old versions of IE due to folks testing using IE's unreliable emulation modes.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function emulatedIEMajorVersion() {
|
||||
var groups = /MSIE ([0-9.]+)/.exec(window.navigator.userAgent)
|
||||
if (groups === null) {
|
||||
return null
|
||||
}
|
||||
var ieVersionNum = parseInt(groups[1], 10)
|
||||
var ieMajorVersion = Math.floor(ieVersionNum)
|
||||
return ieMajorVersion
|
||||
}
|
||||
|
||||
function actualNonEmulatedIEMajorVersion() {
|
||||
// Detects the actual version of IE in use, even if it's in an older-IE emulation mode.
|
||||
// IE JavaScript conditional compilation docs: https://msdn.microsoft.com/library/121hztk3%28v=vs.94%29.aspx
|
||||
// @cc_on docs: https://msdn.microsoft.com/library/8ka90k2e%28v=vs.94%29.aspx
|
||||
var jscriptVersion = new Function('/*@cc_on return @_jscript_version; @*/')() // jshint ignore:line
|
||||
if (jscriptVersion === undefined) {
|
||||
return 11 // IE11+ not in emulation mode
|
||||
}
|
||||
if (jscriptVersion < 9) {
|
||||
return 8 // IE8 (or lower; haven't tested on IE<8)
|
||||
}
|
||||
return jscriptVersion // IE9 or IE10 in any mode, or IE11 in non-IE11 mode
|
||||
}
|
||||
|
||||
var ua = window.navigator.userAgent
|
||||
if (ua.indexOf('Opera') > -1 || ua.indexOf('Presto') > -1) {
|
||||
return // Opera, which might pretend to be IE
|
||||
}
|
||||
var emulated = emulatedIEMajorVersion()
|
||||
if (emulated === null) {
|
||||
return // Not IE
|
||||
}
|
||||
var nonEmulated = actualNonEmulatedIEMajorVersion()
|
||||
|
||||
if (emulated !== nonEmulated) {
|
||||
window.alert('WARNING: You appear to be using IE' + nonEmulated + ' in IE' + emulated + ' emulation mode.\nIE emulation modes can behave significantly differently from ACTUAL older versions of IE.\nPLEASE DON\'T FILE BOOTSTRAP BUGS based on testing in IE emulation modes!')
|
||||
}
|
||||
})();
|
||||
@ -1,23 +0,0 @@
|
||||
/*!
|
||||
* IE10 viewport hack for Surface/desktop Windows 8 bug
|
||||
* Copyright 2014-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
// See the Getting Started docs for more information:
|
||||
// http://getbootstrap.com/getting-started/#support-ie10-width
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
|
||||
var msViewportStyle = document.createElement('style')
|
||||
msViewportStyle.appendChild(
|
||||
document.createTextNode(
|
||||
'@-ms-viewport{width:auto!important}'
|
||||
)
|
||||
)
|
||||
document.querySelector('head').appendChild(msViewportStyle)
|
||||
}
|
||||
|
||||
})();
|
||||
@ -1,273 +0,0 @@
|
||||
/*
|
||||
Styles for older IE versions (previous to 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;
|
||||
margin-bottom: 0;
|
||||
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%;
|
||||
}
|
||||
img.size-full,
|
||||
img.size-large,
|
||||
img.header-image,
|
||||
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 */
|
||||
}
|
||||
.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;
|
||||
max-width: 960px;
|
||||
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;
|
||||
border-top: 1px solid #ededed;
|
||||
display: inline-block !important;
|
||||
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 .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;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
z-index: 1;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
}
|
||||
.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 {
|
||||
border-left: 0;
|
||||
clip: inherit;
|
||||
overflow: inherit;
|
||||
height: inherit;
|
||||
width: inherit;
|
||||
}
|
||||
.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;
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
line-height: 2.181818182;
|
||||
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,
|
||||
.main-navigation .current_page_ancestor > a {
|
||||
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 */
|
||||
.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 {
|
||||
float: left;
|
||||
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 {
|
||||
float: right;
|
||||
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 <IE9 Password Box to make the bullets show up */
|
||||
input[type="password"] {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
/* RTL overrides for IE7 and IE8
|
||||
-------------------------------------------------------------- */
|
||||
.rtl .site-header h1,
|
||||
.rtl .site-header h2 {
|
||||
text-align: right;
|
||||
}
|
||||
.rtl .widget-area,
|
||||
.rtl .author-description {
|
||||
float: left;
|
||||
}
|
||||
.rtl .author-avatar,
|
||||
.rtl .site-content {
|
||||
float: right;
|
||||
}
|
||||
.rtl .main-navigation ul.nav-menu,
|
||||
.rtl .main-navigation div.nav-menu > ul {
|
||||
text-align: right;
|
||||
}
|
||||
.rtl .main-navigation ul li ul li,
|
||||
.rtl .main-navigation ul li ul li ul li {
|
||||
margin-left: 40px;
|
||||
margin-right: auto;
|
||||
}
|
||||
.rtl .main-navigation li ul ul {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
.ie7 .rtl .main-navigation li ul ul {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
.ie7 .rtl .main-navigation ul li {
|
||||
z-index: 99;
|
||||
}
|
||||
.ie7 .rtl .main-navigation li ul {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
.ie7 .rtl .main-navigation li {
|
||||
margin-right: auto;
|
||||
margin-left: 40px;
|
||||
}
|
||||
.ie7 .rtl .main-navigation li ul ul ul {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
/* Make clicks pass-through */
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
background: red;
|
||||
|
||||
position: fixed;
|
||||
z-index: 1031;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
/* Fancy blur effect */
|
||||
#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);
|
||||
}
|
||||
|
||||
/* Remove these to get rid of the spinner */
|
||||
#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); }
|
||||
}
|
||||
|
||||
@ -1,305 +0,0 @@
|
||||
|
||||
.icon-sn-google {
|
||||
background-position: 0 -28px;
|
||||
}
|
||||
|
||||
.icon-sn-bg-google {
|
||||
background-color: #4285f4;
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
.fa-sn-google {
|
||||
color: #4285f4;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.icon-sn-qq {
|
||||
background-position: -84px -28px;
|
||||
}
|
||||
|
||||
.icon-sn-bg-qq {
|
||||
background-color: #0098e6;
|
||||
background-position: -84px 0;
|
||||
}
|
||||
|
||||
.fa-sn-qq {
|
||||
color: #0098e6;
|
||||
}
|
||||
|
||||
.icon-sn-twitter {
|
||||
background-position: -112px -28px;
|
||||
}
|
||||
|
||||
.icon-sn-bg-twitter {
|
||||
background-color: #50abf1;
|
||||
background-position: -112px 0;
|
||||
}
|
||||
|
||||
.fa-sn-twitter {
|
||||
color: #50abf1;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.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('../img/icon-sn.svg');
|
||||
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);
|
||||
}
|
||||
|
||||
.btn-sn-google {
|
||||
background: #4285f4;
|
||||
}
|
||||
|
||||
.btn-sn-google:active, .btn-sn-google:focus, .btn-sn-google:hover {
|
||||
background: #2a75f3;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.btn-sn-qq {
|
||||
background: #0098e6;
|
||||
}
|
||||
|
||||
.btn-sn-qq:active, .btn-sn-qq:focus, .btn-sn-qq:hover {
|
||||
background: #0087cd;
|
||||
}
|
||||
|
||||
.btn-sn-twitter {
|
||||
background: #50abf1;
|
||||
}
|
||||
|
||||
.btn-sn-twitter:active, .btn-sn-twitter:focus, .btn-sn-twitter:hover {
|
||||
background: #38a0ef;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -1,378 +0,0 @@
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKWyV9hmIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKWyV9hvIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKWyV9hnIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKWyV9hoIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKWyV9hkIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKWyV9hlIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKWyV9hrIqM.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem6YaGs126MiZpBA-UFUK0Udc1UAw.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem6YaGs126MiZpBA-UFUK0ddc1UAw.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem6YaGs126MiZpBA-UFUK0Vdc1UAw.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem6YaGs126MiZpBA-UFUK0adc1UAw.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem6YaGs126MiZpBA-UFUK0Wdc1UAw.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem6YaGs126MiZpBA-UFUK0Xdc1UAw.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem6YaGs126MiZpBA-UFUK0Zdc0.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKXGUdhmIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKXGUdhvIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKXGUdhnIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKXGUdhoIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKXGUdhkIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKXGUdhlIqOjjg.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(memnYaGs126MiZpBA-UFUKXGUdhrIqM.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UN_r8OX-hpOqc.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UN_r8OVuhpOqc.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UN_r8OXuhpOqc.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UN_r8OUehpOqc.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UN_r8OXehpOqc.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UN_r8OXOhpOqc.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UN_r8OUuhp.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem8YaGs126MiZpBA-UFWJ0bbck.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem8YaGs126MiZpBA-UFUZ0bbck.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem8YaGs126MiZpBA-UFWZ0bbck.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem8YaGs126MiZpBA-UFVp0bbck.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem8YaGs126MiZpBA-UFWp0bbck.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem8YaGs126MiZpBA-UFW50bbck.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: fallback;
|
||||
src: url(mem8YaGs126MiZpBA-UFVZ0b.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UNirkOX-hpOqc.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UNirkOVuhpOqc.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UNirkOXuhpOqc.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UNirkOUehpOqc.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UNirkOXehpOqc.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UNirkOXOhpOqc.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: fallback;
|
||||
src: url(mem5YaGs126MiZpBA-UNirkOUuhp.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 25 KiB |
@ -1,91 +0,0 @@
|
||||
/**
|
||||
* Created by liangliang on 2016/11/20.
|
||||
*/
|
||||
|
||||
|
||||
function do_reply(parentid) {
|
||||
console.log(parentid);
|
||||
$("#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_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));
|
||||
|
||||
function debounce(func, wait) {
|
||||
var timeout;
|
||||
return function () {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(func, wait);
|
||||
};
|
||||
}
|
||||
|
||||
function slideTopSet() {
|
||||
var top = $(document).scrollTop();
|
||||
|
||||
if (top > 200) {
|
||||
rocket.addClass('show');
|
||||
} else {
|
||||
rocket.removeClass('show');
|
||||
}
|
||||
}
|
||||
|
||||
$(document).on('click', '#rocket', function (event) {
|
||||
rocket.addClass('move');
|
||||
$('body, html').animate({
|
||||
scrollTop: 0
|
||||
}, 800);
|
||||
});
|
||||
$(document).on('animationEnd', function () {
|
||||
setTimeout(function () {
|
||||
rocket.removeClass('move');
|
||||
}, 400);
|
||||
|
||||
});
|
||||
$(document).on('webkitAnimationEnd', function () {
|
||||
setTimeout(function () {
|
||||
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);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// $(document).ready(function () {
|
||||
// var form = $('#i18n-form');
|
||||
// var selector = $('.i18n-select');
|
||||
// selector.on('change', function () {
|
||||
// form.submit();
|
||||
// });
|
||||
// });
|
||||
@ -1,8 +0,0 @@
|
||||
/*
|
||||
HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
*/
|
||||
(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
|
||||
a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}</style>";
|
||||
c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
|
||||
"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);
|
||||
if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);
|
||||
File diff suppressed because one or more lines are too long
@ -1,55 +0,0 @@
|
||||
/**
|
||||
* Handles toggling the navigation menu for small screens and
|
||||
* accessibility for submenu items.
|
||||
*/
|
||||
( function() {
|
||||
var nav = document.getElementById( 'site-navigation' ), button, menu;
|
||||
if ( ! nav ) {
|
||||
return;
|
||||
}
|
||||
|
||||
button = nav.getElementsByTagName( 'button' )[0];
|
||||
menu = nav.getElementsByTagName( 'ul' )[0];
|
||||
if ( ! button ) {
|
||||
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', '' );
|
||||
} else {
|
||||
button.className += ' toggled-on';
|
||||
menu.className += ' toggled-on';
|
||||
}
|
||||
};
|
||||
} )();
|
||||
|
||||
// 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' );
|
||||
|
||||
if ( ! el.hasClass( 'focus' ) ) {
|
||||
e.preventDefault();
|
||||
el.toggleClass( 'focus' );
|
||||
el.siblings( '.focus').removeClass( 'focus' );
|
||||
}
|
||||
} );
|
||||
}
|
||||
} )( jQuery );
|
||||
@ -1,480 +0,0 @@
|
||||
/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
|
||||
* @license MIT */
|
||||
|
||||
;(function(root, factory) {
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
} else {
|
||||
root.NProgress = factory();
|
||||
}
|
||||
|
||||
})(this, function() {
|
||||
var NProgress = {};
|
||||
|
||||
NProgress.version = '0.2.0';
|
||||
|
||||
var Settings = NProgress.settings = {
|
||||
minimum: 0.08,
|
||||
easing: 'linear',
|
||||
positionUsing: '',
|
||||
speed: 200,
|
||||
trickle: true,
|
||||
trickleSpeed: 200,
|
||||
showSpinner: true,
|
||||
barSelector: '[role="bar"]',
|
||||
spinnerSelector: '[role="spinner"]',
|
||||
parent: 'body',
|
||||
template: '<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates configuration.
|
||||
*
|
||||
* NProgress.configure({
|
||||
* minimum: 0.1
|
||||
* });
|
||||
*/
|
||||
NProgress.configure = function(options) {
|
||||
var key, value;
|
||||
for (key in options) {
|
||||
value = options[key];
|
||||
if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Last number.
|
||||
*/
|
||||
|
||||
NProgress.status = null;
|
||||
|
||||
/**
|
||||
* Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.
|
||||
*
|
||||
* NProgress.set(0.4);
|
||||
* NProgress.set(1.0);
|
||||
*/
|
||||
|
||||
NProgress.set = function(n) {
|
||||
var started = NProgress.isStarted();
|
||||
|
||||
n = clamp(n, Settings.minimum, 1);
|
||||
NProgress.status = (n === 1 ? null : n);
|
||||
|
||||
var progress = NProgress.render(!started),
|
||||
bar = progress.querySelector(Settings.barSelector),
|
||||
speed = Settings.speed,
|
||||
ease = Settings.easing;
|
||||
|
||||
progress.offsetWidth; /* Repaint */
|
||||
|
||||
queue(function(next) {
|
||||
// Set positionUsing if it hasn't already been set
|
||||
if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();
|
||||
|
||||
// Add transition
|
||||
css(bar, barPositionCSS(n, speed, ease));
|
||||
|
||||
if (n === 1) {
|
||||
// Fade out
|
||||
css(progress, {
|
||||
transition: 'none',
|
||||
opacity: 1
|
||||
});
|
||||
progress.offsetWidth; /* Repaint */
|
||||
|
||||
setTimeout(function() {
|
||||
css(progress, {
|
||||
transition: 'all ' + speed + 'ms linear',
|
||||
opacity: 0
|
||||
});
|
||||
setTimeout(function() {
|
||||
NProgress.remove();
|
||||
next();
|
||||
}, speed);
|
||||
}, speed);
|
||||
} else {
|
||||
setTimeout(next, speed);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
NProgress.isStarted = function() {
|
||||
return typeof NProgress.status === 'number';
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the progress bar.
|
||||
* This is the same as setting the status to 0%, except that it doesn't go backwards.
|
||||
*
|
||||
* NProgress.start();
|
||||
*
|
||||
*/
|
||||
NProgress.start = function() {
|
||||
if (!NProgress.status) NProgress.set(0);
|
||||
|
||||
var work = function() {
|
||||
setTimeout(function() {
|
||||
if (!NProgress.status) return;
|
||||
NProgress.trickle();
|
||||
work();
|
||||
}, Settings.trickleSpeed);
|
||||
};
|
||||
|
||||
if (Settings.trickle) work();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides the progress bar.
|
||||
* This is the *sort of* the same as setting the status to 100%, with the
|
||||
* difference being `done()` makes some placebo effect of some realistic motion.
|
||||
*
|
||||
* NProgress.done();
|
||||
*
|
||||
* If `true` is passed, it will show the progress bar even if its hidden.
|
||||
*
|
||||
* NProgress.done(true);
|
||||
*/
|
||||
|
||||
NProgress.done = function(force) {
|
||||
if (!force && !NProgress.status) return this;
|
||||
|
||||
return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Increments by a random amount.
|
||||
*/
|
||||
|
||||
NProgress.inc = function(amount) {
|
||||
var n = NProgress.status;
|
||||
|
||||
if (!n) {
|
||||
return NProgress.start();
|
||||
} else if(n > 1) {
|
||||
|
||||
} else {
|
||||
if (typeof amount !== 'number') {
|
||||
if (n >= 0 && n < 0.2) { amount = 0.1; }
|
||||
else if (n >= 0.2 && n < 0.5) { amount = 0.04; }
|
||||
else if (n >= 0.5 && n < 0.8) { amount = 0.02; }
|
||||
else if (n >= 0.8 && n < 0.99) { amount = 0.005; }
|
||||
else { amount = 0; }
|
||||
}
|
||||
|
||||
n = clamp(n + amount, 0, 0.994);
|
||||
return NProgress.set(n);
|
||||
}
|
||||
};
|
||||
|
||||
NProgress.trickle = function() {
|
||||
return NProgress.inc();
|
||||
};
|
||||
|
||||
/**
|
||||
* Waits for all supplied jQuery promises and
|
||||
* increases the progress as the promises resolve.
|
||||
*
|
||||
* @param $promise jQUery Promise
|
||||
*/
|
||||
(function() {
|
||||
var initial = 0, current = 0;
|
||||
|
||||
NProgress.promise = function($promise) {
|
||||
if (!$promise || $promise.state() === "resolved") {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (current === 0) {
|
||||
NProgress.start();
|
||||
}
|
||||
|
||||
initial++;
|
||||
current++;
|
||||
|
||||
$promise.always(function() {
|
||||
current--;
|
||||
if (current === 0) {
|
||||
initial = 0;
|
||||
NProgress.done();
|
||||
} else {
|
||||
NProgress.set((initial - current) / initial);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) renders the progress bar markup based on the `template`
|
||||
* setting.
|
||||
*/
|
||||
|
||||
NProgress.render = function(fromStart) {
|
||||
if (NProgress.isRendered()) return document.getElementById('nprogress');
|
||||
|
||||
addClass(document.documentElement, 'nprogress-busy');
|
||||
|
||||
var progress = document.createElement('div');
|
||||
progress.id = 'nprogress';
|
||||
progress.innerHTML = Settings.template;
|
||||
|
||||
var bar = progress.querySelector(Settings.barSelector),
|
||||
perc = fromStart ? '-100' : toBarPerc(NProgress.status || 0),
|
||||
parent = document.querySelector(Settings.parent),
|
||||
spinner;
|
||||
|
||||
css(bar, {
|
||||
transition: 'all 0 linear',
|
||||
transform: 'translate3d(' + perc + '%,0,0)'
|
||||
});
|
||||
|
||||
if (!Settings.showSpinner) {
|
||||
spinner = progress.querySelector(Settings.spinnerSelector);
|
||||
spinner && removeElement(spinner);
|
||||
}
|
||||
|
||||
if (parent != document.body) {
|
||||
addClass(parent, 'nprogress-custom-parent');
|
||||
}
|
||||
|
||||
parent.appendChild(progress);
|
||||
return progress;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the element. Opposite of render().
|
||||
*/
|
||||
|
||||
NProgress.remove = function() {
|
||||
removeClass(document.documentElement, 'nprogress-busy');
|
||||
removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent');
|
||||
var progress = document.getElementById('nprogress');
|
||||
progress && removeElement(progress);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the progress bar is rendered.
|
||||
*/
|
||||
|
||||
NProgress.isRendered = function() {
|
||||
return !!document.getElementById('nprogress');
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine which positioning CSS rule to use.
|
||||
*/
|
||||
|
||||
NProgress.getPositioningCSS = function() {
|
||||
// Sniff on document.body.style
|
||||
var bodyStyle = document.body.style;
|
||||
|
||||
// Sniff prefixes
|
||||
var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :
|
||||
('MozTransform' in bodyStyle) ? 'Moz' :
|
||||
('msTransform' in bodyStyle) ? 'ms' :
|
||||
('OTransform' in bodyStyle) ? 'O' : '';
|
||||
|
||||
if (vendorPrefix + 'Perspective' in bodyStyle) {
|
||||
// Modern browsers with 3D support, e.g. Webkit, IE10
|
||||
return 'translate3d';
|
||||
} else if (vendorPrefix + 'Transform' in bodyStyle) {
|
||||
// Browsers without 3D support, e.g. IE9
|
||||
return 'translate';
|
||||
} else {
|
||||
// Browsers without translate() support, e.g. IE7-8
|
||||
return 'margin';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function clamp(n, min, max) {
|
||||
if (n < min) return min;
|
||||
if (n > max) return max;
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) converts a percentage (`0..1`) to a bar translateX
|
||||
* percentage (`-100%..0%`).
|
||||
*/
|
||||
|
||||
function toBarPerc(n) {
|
||||
return (-1 + n) * 100;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* (Internal) returns the correct CSS for changing the bar's
|
||||
* position given an n percentage, and speed and ease from Settings
|
||||
*/
|
||||
|
||||
function barPositionCSS(n, speed, ease) {
|
||||
var barCSS;
|
||||
|
||||
if (Settings.positionUsing === 'translate3d') {
|
||||
barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };
|
||||
} else if (Settings.positionUsing === 'translate') {
|
||||
barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };
|
||||
} else {
|
||||
barCSS = { 'margin-left': toBarPerc(n)+'%' };
|
||||
}
|
||||
|
||||
barCSS.transition = 'all '+speed+'ms '+ease;
|
||||
|
||||
return barCSS;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Queues a function to be executed.
|
||||
*/
|
||||
|
||||
var queue = (function() {
|
||||
var pending = [];
|
||||
|
||||
function next() {
|
||||
var fn = pending.shift();
|
||||
if (fn) {
|
||||
fn(next);
|
||||
}
|
||||
}
|
||||
|
||||
return function(fn) {
|
||||
pending.push(fn);
|
||||
if (pending.length == 1) next();
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) Applies css properties to an element, similar to the jQuery
|
||||
* css method.
|
||||
*
|
||||
* While this helper does assist with vendor prefixed property names, it
|
||||
* does not perform any manipulation of values prior to setting styles.
|
||||
*/
|
||||
|
||||
var css = (function() {
|
||||
var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],
|
||||
cssProps = {};
|
||||
|
||||
function camelCase(string) {
|
||||
return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function(match, letter) {
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
function getVendorProp(name) {
|
||||
var style = document.body.style;
|
||||
if (name in style) return name;
|
||||
|
||||
var i = cssPrefixes.length,
|
||||
capName = name.charAt(0).toUpperCase() + name.slice(1),
|
||||
vendorName;
|
||||
while (i--) {
|
||||
vendorName = cssPrefixes[i] + capName;
|
||||
if (vendorName in style) return vendorName;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function getStyleProp(name) {
|
||||
name = camelCase(name);
|
||||
return cssProps[name] || (cssProps[name] = getVendorProp(name));
|
||||
}
|
||||
|
||||
function applyCss(element, prop, value) {
|
||||
prop = getStyleProp(prop);
|
||||
element.style[prop] = value;
|
||||
}
|
||||
|
||||
return function(element, properties) {
|
||||
var args = arguments,
|
||||
prop,
|
||||
value;
|
||||
|
||||
if (args.length == 2) {
|
||||
for (prop in properties) {
|
||||
value = properties[prop];
|
||||
if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);
|
||||
}
|
||||
} else {
|
||||
applyCss(element, args[1], args[2]);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* (Internal) Determines if an element or space separated list of class names contains a class name.
|
||||
*/
|
||||
|
||||
function hasClass(element, name) {
|
||||
var list = typeof element == 'string' ? element : classList(element);
|
||||
return list.indexOf(' ' + name + ' ') >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Adds a class to an element.
|
||||
*/
|
||||
|
||||
function addClass(element, name) {
|
||||
var oldList = classList(element),
|
||||
newList = oldList + name;
|
||||
|
||||
if (hasClass(oldList, name)) return;
|
||||
|
||||
// Trim the opening space.
|
||||
element.className = newList.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Removes a class from an element.
|
||||
*/
|
||||
|
||||
function removeClass(element, name) {
|
||||
var oldList = classList(element),
|
||||
newList;
|
||||
|
||||
if (!hasClass(element, name)) return;
|
||||
|
||||
// Replace the class name.
|
||||
newList = oldList.replace(' ' + name + ' ', ' ');
|
||||
|
||||
// Trim the opening and closing spaces.
|
||||
element.className = newList.substring(1, newList.length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Gets a space separated list of the class names on the element.
|
||||
* The list is wrapped with a single space on each end to facilitate finding
|
||||
* matches within the list.
|
||||
*/
|
||||
|
||||
function classList(element) {
|
||||
return (' ' + (element && element.className || '') + ' ').replace(/\s+/gi, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* (Internal) Removes an element from the DOM.
|
||||
*/
|
||||
|
||||
function removeElement(element) {
|
||||
element && element.parentNode && element.parentNode.removeChild(element);
|
||||
}
|
||||
|
||||
return NProgress;
|
||||
});
|
||||
@ -1,21 +0,0 @@
|
||||
$(function () {
|
||||
MathJax.Hub.Config({
|
||||
showProcessingMessages: false, //关闭js加载过程信息
|
||||
messageStyle: "none", //不显示信息
|
||||
extensions: ["tex2jax.js"], jax: ["input/TeX", "output/HTML-CSS"], displayAlign: "left", tex2jax: {
|
||||
inlineMath: [["$", "$"]], //行内公式选择$
|
||||
displayMath: [["$$", "$$"]], //段内公式选择$$
|
||||
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code', 'a'], //避开某些标签
|
||||
}, "HTML-CSS": {
|
||||
availableFonts: ["STIX", "TeX"], //可选字体
|
||||
showMathMenu: false //关闭右击菜单显示
|
||||
}
|
||||
});
|
||||
// 识别范围 => 文章内容、评论内容标签
|
||||
const contentId = document.getElementById("content");
|
||||
const commentId = document.getElementById("comments");
|
||||
MathJax.Hub.Queue(["Typeset", MathJax.Hub, contentId, commentId]);
|
||||
})
|
||||
|
||||
|
||||
|
||||
@ -1,293 +0,0 @@
|
||||
.codehilite .hll {
|
||||
background-color: #ffffcc
|
||||
}
|
||||
|
||||
.codehilite {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.codehilite .c {
|
||||
color: #177500
|
||||
}
|
||||
|
||||
/* Comment */
|
||||
.codehilite .err {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Error */
|
||||
.codehilite .k {
|
||||
color: #A90D91
|
||||
}
|
||||
|
||||
/* Keyword */
|
||||
.codehilite .l {
|
||||
color: #1C01CE
|
||||
}
|
||||
|
||||
/* Literal */
|
||||
.codehilite .n {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name */
|
||||
.codehilite .o {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Operator */
|
||||
.codehilite .ch {
|
||||
color: #177500
|
||||
}
|
||||
|
||||
/* Comment.Hashbang */
|
||||
.codehilite .cm {
|
||||
color: #177500
|
||||
}
|
||||
|
||||
/* Comment.Multiline */
|
||||
.codehilite .cp {
|
||||
color: #633820
|
||||
}
|
||||
|
||||
/* Comment.Preproc */
|
||||
.codehilite .cpf {
|
||||
color: #177500
|
||||
}
|
||||
|
||||
/* Comment.PreprocFile */
|
||||
.codehilite .c1 {
|
||||
color: #177500
|
||||
}
|
||||
|
||||
/* Comment.Single */
|
||||
.codehilite .cs {
|
||||
color: #177500
|
||||
}
|
||||
|
||||
/* Comment.Special */
|
||||
.codehilite .kc {
|
||||
color: #A90D91
|
||||
}
|
||||
|
||||
/* Keyword.Constant */
|
||||
.codehilite .kd {
|
||||
color: #A90D91
|
||||
}
|
||||
|
||||
/* Keyword.Declaration */
|
||||
.codehilite .kn {
|
||||
color: #A90D91
|
||||
}
|
||||
|
||||
/* Keyword.Namespace */
|
||||
.codehilite .kp {
|
||||
color: #A90D91
|
||||
}
|
||||
|
||||
/* Keyword.Pseudo */
|
||||
.codehilite .kr {
|
||||
color: #A90D91
|
||||
}
|
||||
|
||||
/* Keyword.Reserved */
|
||||
.codehilite .kt {
|
||||
color: #A90D91
|
||||
}
|
||||
|
||||
/* Keyword.Type */
|
||||
.codehilite .ld {
|
||||
color: #1C01CE
|
||||
}
|
||||
|
||||
/* Literal.Date */
|
||||
.codehilite .m {
|
||||
color: #1C01CE
|
||||
}
|
||||
|
||||
/* Literal.Number */
|
||||
.codehilite .s {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String */
|
||||
.codehilite .na {
|
||||
color: #836C28
|
||||
}
|
||||
|
||||
/* Name.Attribute */
|
||||
.codehilite .nb {
|
||||
color: #A90D91
|
||||
}
|
||||
|
||||
/* Name.Builtin */
|
||||
.codehilite .nc {
|
||||
color: #3F6E75
|
||||
}
|
||||
|
||||
/* Name.Class */
|
||||
.codehilite .no {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Constant */
|
||||
.codehilite .nd {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Decorator */
|
||||
.codehilite .ni {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Entity */
|
||||
.codehilite .ne {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Exception */
|
||||
.codehilite .nf {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Function */
|
||||
.codehilite .nl {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Label */
|
||||
.codehilite .nn {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Namespace */
|
||||
.codehilite .nx {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Other */
|
||||
.codehilite .py {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Property */
|
||||
.codehilite .nt {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Tag */
|
||||
.codehilite .nv {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Variable */
|
||||
.codehilite .ow {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Operator.Word */
|
||||
.codehilite .mb {
|
||||
color: #1C01CE
|
||||
}
|
||||
|
||||
/* Literal.Number.Bin */
|
||||
.codehilite .mf {
|
||||
color: #1C01CE
|
||||
}
|
||||
|
||||
/* Literal.Number.Float */
|
||||
.codehilite .mh {
|
||||
color: #1C01CE
|
||||
}
|
||||
|
||||
/* Literal.Number.Hex */
|
||||
.codehilite .mi {
|
||||
color: #1C01CE
|
||||
}
|
||||
|
||||
/* Literal.Number.Integer */
|
||||
.codehilite .mo {
|
||||
color: #1C01CE
|
||||
}
|
||||
|
||||
/* Literal.Number.Oct */
|
||||
.codehilite .sb {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String.Backtick */
|
||||
.codehilite .sc {
|
||||
color: #2300CE
|
||||
}
|
||||
|
||||
/* Literal.String.Char */
|
||||
.codehilite .sd {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String.Doc */
|
||||
.codehilite .s2 {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String.Double */
|
||||
.codehilite .se {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String.Escape */
|
||||
.codehilite .sh {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String.Heredoc */
|
||||
.codehilite .si {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String.Interpol */
|
||||
.codehilite .sx {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String.Other */
|
||||
.codehilite .sr {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String.Regex */
|
||||
.codehilite .s1 {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String.Single */
|
||||
.codehilite .ss {
|
||||
color: #C41A16
|
||||
}
|
||||
|
||||
/* Literal.String.Symbol */
|
||||
.codehilite .bp {
|
||||
color: #5B269A
|
||||
}
|
||||
|
||||
/* Name.Builtin.Pseudo */
|
||||
.codehilite .vc {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Variable.Class */
|
||||
.codehilite .vg {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Variable.Global */
|
||||
.codehilite .vi {
|
||||
color: #000000
|
||||
}
|
||||
|
||||
/* Name.Variable.Instance */
|
||||
.codehilite .il {
|
||||
color: #1C01CE
|
||||
}
|
||||
|
||||
/* Literal.Number.Integer.Long */
|
||||
@ -1,5 +0,0 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class AccountsConfig(AppConfig):
|
||||
name = 'accounts'
|
||||
@ -1,117 +0,0 @@
|
||||
from django import forms
|
||||
from django.contrib.auth import get_user_model, password_validation
|
||||
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.forms import widgets
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from . import utils
|
||||
from .models import BlogUser
|
||||
|
||||
|
||||
class LoginForm(AuthenticationForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LoginForm, self).__init__(*args, **kwargs)
|
||||
self.fields['username'].widget = widgets.TextInput(
|
||||
attrs={'placeholder': "username", "class": "form-control"})
|
||||
self.fields['password'].widget = widgets.PasswordInput(
|
||||
attrs={'placeholder': "password", "class": "form-control"})
|
||||
|
||||
|
||||
class RegisterForm(UserCreationForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RegisterForm, self).__init__(*args, **kwargs)
|
||||
|
||||
self.fields['username'].widget = widgets.TextInput(
|
||||
attrs={'placeholder': "username", "class": "form-control"})
|
||||
self.fields['email'].widget = widgets.EmailInput(
|
||||
attrs={'placeholder': "email", "class": "form-control"})
|
||||
self.fields['password1'].widget = widgets.PasswordInput(
|
||||
attrs={'placeholder': "password", "class": "form-control"})
|
||||
self.fields['password2'].widget = widgets.PasswordInput(
|
||||
attrs={'placeholder': "repeat password", "class": "form-control"})
|
||||
|
||||
def clean_email(self):
|
||||
email = self.cleaned_data['email']
|
||||
if get_user_model().objects.filter(email=email).exists():
|
||||
raise ValidationError(_("email already exists"))
|
||||
return email
|
||||
|
||||
class Meta:
|
||||
model = get_user_model()
|
||||
fields = ("username", "email")
|
||||
|
||||
|
||||
class ForgetPasswordForm(forms.Form):
|
||||
new_password1 = forms.CharField(
|
||||
label=_("New password"),
|
||||
widget=forms.PasswordInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
'placeholder': _("New password")
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
new_password2 = forms.CharField(
|
||||
label="确认密码",
|
||||
widget=forms.PasswordInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
'placeholder': _("Confirm password")
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
email = forms.EmailField(
|
||||
label='邮箱',
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
'class': 'form-control',
|
||||
'placeholder': _("Email")
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
code = forms.CharField(
|
||||
label=_('Code'),
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
'class': 'form-control',
|
||||
'placeholder': _("Code")
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
def clean_new_password2(self):
|
||||
password1 = self.data.get("new_password1")
|
||||
password2 = self.data.get("new_password2")
|
||||
if password1 and password2 and password1 != password2:
|
||||
raise ValidationError(_("passwords do not match"))
|
||||
password_validation.validate_password(password2)
|
||||
|
||||
return password2
|
||||
|
||||
def clean_email(self):
|
||||
user_email = self.cleaned_data.get("email")
|
||||
if not BlogUser.objects.filter(
|
||||
email=user_email
|
||||
).exists():
|
||||
# todo 这里的报错提示可以判断一个邮箱是不是注册过,如果不想暴露可以修改
|
||||
raise ValidationError(_("email does not exist"))
|
||||
return user_email
|
||||
|
||||
def clean_code(self):
|
||||
code = self.cleaned_data.get("code")
|
||||
error = utils.verify(
|
||||
email=self.cleaned_data.get("email"),
|
||||
code=code,
|
||||
)
|
||||
if error:
|
||||
raise ValidationError(error)
|
||||
return code
|
||||
|
||||
|
||||
class ForgetPasswordCodeForm(forms.Form):
|
||||
email = forms.EmailField(
|
||||
label=_('Email'),
|
||||
)
|
||||
@ -1,46 +0,0 @@
|
||||
# Generated by Django 4.2.5 on 2023-09-06 13:13
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('accounts', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='bloguser',
|
||||
options={'get_latest_by': 'id', 'ordering': ['-id'], 'verbose_name': 'user', 'verbose_name_plural': 'user'},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='bloguser',
|
||||
name='created_time',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='bloguser',
|
||||
name='last_mod_time',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='bloguser',
|
||||
name='creation_time',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='bloguser',
|
||||
name='last_modify_time',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='bloguser',
|
||||
name='nickname',
|
||||
field=models.CharField(blank=True, max_length=100, verbose_name='nick name'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='bloguser',
|
||||
name='source',
|
||||
field=models.CharField(blank=True, max_length=100, verbose_name='create source'),
|
||||
),
|
||||
]
|
||||
@ -1,207 +0,0 @@
|
||||
from django.test import Client, RequestFactory, TestCase
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from accounts.models import BlogUser
|
||||
from blog.models import Article, Category
|
||||
from djangoblog.utils import *
|
||||
from . import utils
|
||||
|
||||
|
||||
# Create your tests here.
|
||||
|
||||
class AccountTest(TestCase):
|
||||
def setUp(self):
|
||||
self.client = Client()
|
||||
self.factory = RequestFactory()
|
||||
self.blog_user = BlogUser.objects.create_user(
|
||||
username="test",
|
||||
email="admin@admin.com",
|
||||
password="12345678"
|
||||
)
|
||||
self.new_test = "xxx123--="
|
||||
|
||||
def test_validate_account(self):
|
||||
site = get_current_site().domain
|
||||
user = BlogUser.objects.create_superuser(
|
||||
email="liangliangyy1@gmail.com",
|
||||
username="liangliangyy1",
|
||||
password="qwer!@#$ggg")
|
||||
testuser = BlogUser.objects.get(username='liangliangyy1')
|
||||
|
||||
loginresult = self.client.login(
|
||||
username='liangliangyy1',
|
||||
password='qwer!@#$ggg')
|
||||
self.assertEqual(loginresult, True)
|
||||
response = self.client.get('/admin/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
category = Category()
|
||||
category.name = "categoryaaa"
|
||||
category.creation_time = timezone.now()
|
||||
category.last_modify_time = timezone.now()
|
||||
category.save()
|
||||
|
||||
article = Article()
|
||||
article.title = "nicetitleaaa"
|
||||
article.body = "nicecontentaaa"
|
||||
article.author = user
|
||||
article.category = category
|
||||
article.type = 'a'
|
||||
article.status = 'p'
|
||||
article.save()
|
||||
|
||||
response = self.client.get(article.get_admin_url())
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_validate_register(self):
|
||||
self.assertEquals(
|
||||
0, len(
|
||||
BlogUser.objects.filter(
|
||||
email='user123@user.com')))
|
||||
response = self.client.post(reverse('account:register'), {
|
||||
'username': 'user1233',
|
||||
'email': 'user123@user.com',
|
||||
'password1': 'password123!q@wE#R$T',
|
||||
'password2': 'password123!q@wE#R$T',
|
||||
})
|
||||
self.assertEquals(
|
||||
1, len(
|
||||
BlogUser.objects.filter(
|
||||
email='user123@user.com')))
|
||||
user = BlogUser.objects.filter(email='user123@user.com')[0]
|
||||
sign = get_sha256(get_sha256(settings.SECRET_KEY + str(user.id)))
|
||||
path = reverse('accounts:result')
|
||||
url = '{path}?type=validation&id={id}&sign={sign}'.format(
|
||||
path=path, id=user.id, sign=sign)
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.client.login(username='user1233', password='password123!q@wE#R$T')
|
||||
user = BlogUser.objects.filter(email='user123@user.com')[0]
|
||||
user.is_superuser = True
|
||||
user.is_staff = True
|
||||
user.save()
|
||||
delete_sidebar_cache()
|
||||
category = Category()
|
||||
category.name = "categoryaaa"
|
||||
category.creation_time = timezone.now()
|
||||
category.last_modify_time = timezone.now()
|
||||
category.save()
|
||||
|
||||
article = Article()
|
||||
article.category = category
|
||||
article.title = "nicetitle333"
|
||||
article.body = "nicecontentttt"
|
||||
article.author = user
|
||||
|
||||
article.type = 'a'
|
||||
article.status = 'p'
|
||||
article.save()
|
||||
|
||||
response = self.client.get(article.get_admin_url())
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response = self.client.get(reverse('account:logout'))
|
||||
self.assertIn(response.status_code, [301, 302, 200])
|
||||
|
||||
response = self.client.get(article.get_admin_url())
|
||||
self.assertIn(response.status_code, [301, 302, 200])
|
||||
|
||||
response = self.client.post(reverse('account:login'), {
|
||||
'username': 'user1233',
|
||||
'password': 'password123'
|
||||
})
|
||||
self.assertIn(response.status_code, [301, 302, 200])
|
||||
|
||||
response = self.client.get(article.get_admin_url())
|
||||
self.assertIn(response.status_code, [301, 302, 200])
|
||||
|
||||
def test_verify_email_code(self):
|
||||
to_email = "admin@admin.com"
|
||||
code = generate_code()
|
||||
utils.set_code(to_email, code)
|
||||
utils.send_verify_email(to_email, code)
|
||||
|
||||
err = utils.verify("admin@admin.com", code)
|
||||
self.assertEqual(err, None)
|
||||
|
||||
err = utils.verify("admin@123.com", code)
|
||||
self.assertEqual(type(err), str)
|
||||
|
||||
def test_forget_password_email_code_success(self):
|
||||
resp = self.client.post(
|
||||
path=reverse("account:forget_password_code"),
|
||||
data=dict(email="admin@admin.com")
|
||||
)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(resp.content.decode("utf-8"), "ok")
|
||||
|
||||
def test_forget_password_email_code_fail(self):
|
||||
resp = self.client.post(
|
||||
path=reverse("account:forget_password_code"),
|
||||
data=dict()
|
||||
)
|
||||
self.assertEqual(resp.content.decode("utf-8"), "错误的邮箱")
|
||||
|
||||
resp = self.client.post(
|
||||
path=reverse("account:forget_password_code"),
|
||||
data=dict(email="admin@com")
|
||||
)
|
||||
self.assertEqual(resp.content.decode("utf-8"), "错误的邮箱")
|
||||
|
||||
def test_forget_password_email_success(self):
|
||||
code = generate_code()
|
||||
utils.set_code(self.blog_user.email, code)
|
||||
data = dict(
|
||||
new_password1=self.new_test,
|
||||
new_password2=self.new_test,
|
||||
email=self.blog_user.email,
|
||||
code=code,
|
||||
)
|
||||
resp = self.client.post(
|
||||
path=reverse("account:forget_password"),
|
||||
data=data
|
||||
)
|
||||
self.assertEqual(resp.status_code, 302)
|
||||
|
||||
# 验证用户密码是否修改成功
|
||||
blog_user = BlogUser.objects.filter(
|
||||
email=self.blog_user.email,
|
||||
).first() # type: BlogUser
|
||||
self.assertNotEqual(blog_user, None)
|
||||
self.assertEqual(blog_user.check_password(data["new_password1"]), True)
|
||||
|
||||
def test_forget_password_email_not_user(self):
|
||||
data = dict(
|
||||
new_password1=self.new_test,
|
||||
new_password2=self.new_test,
|
||||
email="123@123.com",
|
||||
code="123456",
|
||||
)
|
||||
resp = self.client.post(
|
||||
path=reverse("account:forget_password"),
|
||||
data=data
|
||||
)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
|
||||
def test_forget_password_email_code_error(self):
|
||||
code = generate_code()
|
||||
utils.set_code(self.blog_user.email, code)
|
||||
data = dict(
|
||||
new_password1=self.new_test,
|
||||
new_password2=self.new_test,
|
||||
email=self.blog_user.email,
|
||||
code="111111",
|
||||
)
|
||||
resp = self.client.post(
|
||||
path=reverse("account:forget_password"),
|
||||
data=data
|
||||
)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
from django.urls import path
|
||||
from django.urls import re_path
|
||||
|
||||
from . import views
|
||||
from .forms import LoginForm
|
||||
|
||||
app_name = "accounts"
|
||||
|
||||
urlpatterns = [re_path(r'^login/$',
|
||||
views.LoginView.as_view(success_url='/'),
|
||||
name='login',
|
||||
kwargs={'authentication_form': LoginForm}),
|
||||
re_path(r'^register/$',
|
||||
views.RegisterView.as_view(success_url="/"),
|
||||
name='register'),
|
||||
re_path(r'^logout/$',
|
||||
views.LogoutView.as_view(),
|
||||
name='logout'),
|
||||
path(r'account/result.html',
|
||||
views.account_result,
|
||||
name='result'),
|
||||
re_path(r'^forget_password/$',
|
||||
views.ForgetPasswordView.as_view(),
|
||||
name='forget_password'),
|
||||
re_path(r'^forget_password_code/$',
|
||||
views.ForgetPasswordEmailCode.as_view(),
|
||||
name='forget_password_code'),
|
||||
]
|
||||
@ -1,26 +0,0 @@
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.backends import ModelBackend
|
||||
|
||||
|
||||
class EmailOrUsernameModelBackend(ModelBackend):
|
||||
"""
|
||||
允许使用用户名或邮箱登录
|
||||
"""
|
||||
|
||||
def authenticate(self, request, username=None, password=None, **kwargs):
|
||||
if '@' in username:
|
||||
kwargs = {'email': username}
|
||||
else:
|
||||
kwargs = {'username': username}
|
||||
try:
|
||||
user = get_user_model().objects.get(**kwargs)
|
||||
if user.check_password(password):
|
||||
return user
|
||||
except get_user_model().DoesNotExist:
|
||||
return None
|
||||
|
||||
def get_user(self, username):
|
||||
try:
|
||||
return get_user_model().objects.get(pk=username)
|
||||
except get_user_model().DoesNotExist:
|
||||
return None
|
||||
@ -1,47 +0,0 @@
|
||||
from django.contrib import admin
|
||||
from django.urls import reverse
|
||||
from django.utils.html import format_html
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
def disable_commentstatus(modeladmin, request, queryset):
|
||||
queryset.update(is_enable=False)
|
||||
|
||||
|
||||
def enable_commentstatus(modeladmin, request, queryset):
|
||||
queryset.update(is_enable=True)
|
||||
|
||||
|
||||
disable_commentstatus.short_description = _('Disable comments')
|
||||
enable_commentstatus.short_description = _('Enable comments')
|
||||
|
||||
|
||||
class CommentAdmin(admin.ModelAdmin):
|
||||
list_per_page = 20
|
||||
list_display = (
|
||||
'id',
|
||||
'body',
|
||||
'link_to_userinfo',
|
||||
'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):
|
||||
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(
|
||||
u'<a href="%s">%s</a>' %
|
||||
(link, obj.author.nickname if obj.author.nickname else obj.author.email))
|
||||
|
||||
def link_to_article(self, obj):
|
||||
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'<a href="%s">%s</a>' % (link, obj.article.title))
|
||||
|
||||
link_to_userinfo.short_description = _('User')
|
||||
link_to_article.short_description = _('Article')
|
||||
@ -1,13 +0,0 @@
|
||||
from django import forms
|
||||
from django.forms import ModelForm
|
||||
|
||||
from .models import Comment
|
||||
|
||||
|
||||
class CommentForm(ModelForm):
|
||||
parent_comment_id = forms.IntegerField(
|
||||
widget=forms.HiddenInput, required=False)
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['body']
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.1.7 on 2023-04-24 13:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('comments', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='comment',
|
||||
name='is_enable',
|
||||
field=models.BooleanField(default=False, verbose_name='是否显示'),
|
||||
),
|
||||
]
|
||||
@ -1,60 +0,0 @@
|
||||
# Generated by Django 4.2.5 on 2023-09-06 13:13
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
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 = [
|
||||
migrations.AlterModelOptions(
|
||||
name='comment',
|
||||
options={'get_latest_by': 'id', 'ordering': ['-id'], 'verbose_name': 'comment', 'verbose_name_plural': 'comment'},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='comment',
|
||||
name='created_time',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='comment',
|
||||
name='last_mod_time',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='comment',
|
||||
name='creation_time',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='comment',
|
||||
name='last_modify_time',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='comment',
|
||||
name='article',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.article', verbose_name='article'),
|
||||
),
|
||||
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'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='comment',
|
||||
name='is_enable',
|
||||
field=models.BooleanField(default=False, verbose_name='enable'),
|
||||
),
|
||||
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'),
|
||||
),
|
||||
]
|
||||
@ -1,39 +0,0 @@
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from blog.models import Article
|
||||
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class Comment(models.Model):
|
||||
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)
|
||||
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'
|
||||
|
||||
def __str__(self):
|
||||
return self.body
|
||||
@ -1,109 +0,0 @@
|
||||
from django.test import Client, RequestFactory, TransactionTestCase
|
||||
from django.urls import reverse
|
||||
|
||||
from accounts.models import BlogUser
|
||||
from blog.models import Category, Article
|
||||
from comments.models import Comment
|
||||
from comments.templatetags.comments_tags import *
|
||||
from djangoblog.utils import get_max_articleid_commentid
|
||||
|
||||
|
||||
# Create your tests here.
|
||||
|
||||
class CommentsTest(TransactionTestCase):
|
||||
def setUp(self):
|
||||
self.client = Client()
|
||||
self.factory = RequestFactory()
|
||||
from blog.models import BlogSettings
|
||||
value = BlogSettings()
|
||||
value.comment_need_review = True
|
||||
value.save()
|
||||
|
||||
self.user = BlogUser.objects.create_superuser(
|
||||
email="liangliangyy1@gmail.com",
|
||||
username="liangliangyy1",
|
||||
password="liangliangyy1")
|
||||
|
||||
def update_article_comment_status(self, 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"
|
||||
article.author = self.user
|
||||
article.category = category
|
||||
article.type = 'a'
|
||||
article.status = 'p'
|
||||
article.save()
|
||||
|
||||
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)
|
||||
|
||||
self.assertEqual(len(article.comment_list()), 1)
|
||||
|
||||
response = self.client.post(comment_url,
|
||||
{
|
||||
'body': '123ffffffffff',
|
||||
})
|
||||
|
||||
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)
|
||||
parent_comment_id = article.comment_list()[0].id
|
||||
|
||||
response = self.client.post(comment_url,
|
||||
{
|
||||
'body': '''
|
||||
# Title1
|
||||
|
||||
```python
|
||||
import os
|
||||
```
|
||||
|
||||
[url](https://www.lylinux.net/)
|
||||
|
||||
[ddd](http://www.baidu.com)
|
||||
|
||||
|
||||
''',
|
||||
'parent_comment_id': parent_comment_id
|
||||
})
|
||||
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.update_article_comment_status(article)
|
||||
article = Article.objects.get(pk=article.pk)
|
||||
self.assertEqual(len(article.comment_list()), 3)
|
||||
comment = Comment.objects.get(id=parent_comment_id)
|
||||
tree = parse_commenttree(article.comment_list(), comment)
|
||||
self.assertEqual(len(tree), 1)
|
||||
data = show_comment_item(comment, True)
|
||||
self.assertIsNotNone(data)
|
||||
s = get_max_articleid_commentid()
|
||||
self.assertIsNotNone(s)
|
||||
|
||||
from comments.utils import send_comment_email
|
||||
send_comment_email(comment)
|
||||
@ -1,11 +0,0 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = "comments"
|
||||
urlpatterns = [
|
||||
path(
|
||||
'article/<int:article_id>/postcomment',
|
||||
views.CommentPostView.as_view(),
|
||||
name='postcomment'),
|
||||
]
|
||||
@ -1,38 +0,0 @@
|
||||
import logging
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from djangoblog.utils import get_current_site
|
||||
from djangoblog.utils import send_email
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def send_comment_email(comment):
|
||||
site = get_current_site().domain
|
||||
subject = _('Thanks for your comment')
|
||||
article_url = f"https://{site}{comment.article.get_absolute_url()}"
|
||||
html_content = _("""<p>Thank you very much for your comments on this site</p>
|
||||
You can visit <a href="%(article_url)s" rel="bookmark">%(article_title)s</a>
|
||||
to review your comments,
|
||||
Thank you again!
|
||||
<br />
|
||||
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 <a href="%(article_url)s" rel="bookmark">%(article_title)s</a><br/> has
|
||||
received a reply. <br/> %(comment_body)s
|
||||
<br/>
|
||||
go check it out!
|
||||
<br/>
|
||||
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,
|
||||
'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)
|
||||
@ -1,63 +0,0 @@
|
||||
# Create your views here.
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.csrf import csrf_protect
|
||||
from django.views.generic.edit import FormView
|
||||
|
||||
from accounts.models import BlogUser
|
||||
from blog.models import Article
|
||||
from .forms import CommentForm
|
||||
from .models import Comment
|
||||
|
||||
|
||||
class CommentPostView(FormView):
|
||||
form_class = CommentForm
|
||||
template_name = 'blog/article_detail.html'
|
||||
|
||||
@method_decorator(csrf_protect)
|
||||
def dispatch(self, *args, **kwargs):
|
||||
return super(CommentPostView, self).dispatch(*args, **kwargs)
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
article_id = self.kwargs['article_id']
|
||||
article = get_object_or_404(Article, pk=article_id)
|
||||
url = article.get_absolute_url()
|
||||
return HttpResponseRedirect(url + "#comments")
|
||||
|
||||
def form_invalid(self, form):
|
||||
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):
|
||||
"""提交的数据验证合法后的逻辑"""
|
||||
user = self.request.user
|
||||
author = BlogUser.objects.get(pk=user.pk)
|
||||
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))
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue