697 Commits

Author SHA1 Message Date
Copilot
4079a64a88 修复 PHP 8.5 中 curl_close() 弃用警告 (#1924)
* Initial plan

* 移除 curl_close() 调用以修复 PHP 8.5 弃用警告

Co-authored-by: joyqi <59437+joyqi@users.noreply.github.com>

* 使用 PHP 版本检查兼容 PHP 7.4 的 curl_close 处理

Co-authored-by: joyqi <59437+joyqi@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: joyqi <59437+joyqi@users.noreply.github.com>
2025-11-27 11:37:42 +08:00
猫东东
9364388035 修复 PHP 8.4+ 中 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY 的弃用警告 (#1922) 2025-11-27 09:05:18 +08:00
Luffy
7a3c86a110 Support connect to mysql using socket (#1749)
* Support connect to mysql using socket

* pgsql can also use unix_socket

fix Deprecated: pg_escape_string(): Automatic fetching of PostgreSQL connection

* Update install.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update var/Typecho/Db/Adapter/Mysqli.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Fix quoteValue method to correctly escape single quotes in strings

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-20 23:55:43 +08:00
Luffy
15967ea059 Fix login failed when username contains @ (#1894)
* Fix login failed when username contains @

* Update var/Widget/User.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-20 17:17:31 +08:00
Luffy
570f982709 Add 'NOT' to query keywords (#1903) 2025-11-19 22:28:13 +08:00
Luffy
6dbcdf7eae Fix explicitly declare nullable type for $rules parameter (#1908) 2025-08-08 12:09:21 +08:00
joyqi
5e7e10969e fix default theme's i18n problem https://github.com/typecho/languages/issues/49 2025-08-05 11:01:31 +08:00
joyqi
3d261e08b9 fix: don't send ping back to self 2025-08-01 18:04:18 +08:00
joyqi
546470b2de update hyperdown 2025-07-04 15:10:18 +08:00
joyqi
23cdc89441 fix #1882 (#1883) 2025-06-27 11:12:45 +08:00
Luffy
d9d0be334d Update canonical link condition (#1881) 2025-06-11 16:39:39 +08:00
joyqi
ba4e4134ad fix form validate error 2025-06-05 15:10:47 +08:00
joyqi
7ef2c08a96 fix validate error 2025-06-05 15:09:03 +08:00
joyqi
db8a3f7f3e fix nullable parameter error 2025-06-05 14:34:22 +08:00
joyqi
5ef475b73f feat: validate via regexp (#1877) 2025-05-12 23:40:38 +08:00
joyqi
917a763811 Feat/improve styles (#1868)
* improve css

* fix table

* fix write page

* improve header nav

* fix menu

* fix menu

* fix menu

* add flex grid system

* fix

* fix flex

* fix draft version

* using main html element to replace div

* improve css

* add input type number

* fix custom-fields

* fix screen
2025-05-09 16:12:56 +08:00
Robert Silén
50d572a0af Add MariaDB to README.md (#1827) 2025-02-19 10:50:05 +08:00
Luffy
752fc6b0ad Fix missing nameExists and mailExists (#1854) 2025-02-03 10:47:29 +08:00
Luffy
95f6e7b4f5 Remove debug output from category selection in Archive widget (#1852) 2025-02-03 10:40:12 +08:00
Pomelo_Official
67a830f86b fix typo "稍侯" to "稍候" (#1850)
fix typo "稍侯" to "稍候"
2025-01-31 13:35:15 +08:00
Luffy
8ff55f5266 Fix #1846 (#1847) 2025-01-14 21:56:48 +08:00
joyqi
8035b22347 fix #1843 (#1844)
* fix #1843
Remove categroy name-exists detecting

* detect category-exists only in the same level
2025-01-13 16:48:46 +08:00
joyqi
b989f24c5b Fix/1754 (#1842)
* add deprecated methods

* fix #1754
2025-01-11 17:51:29 +08:00
joyqi
23724c4193 fix #1830 (#1841) 2025-01-10 14:53:47 +08:00
joyqi
6ddf1c1a23 fix #1816 (#1839)
* fix #1816

* fix call stack

* fix typo error
2025-01-07 19:42:15 +08:00
Luffy
7d51b210c9 Fix manage comments failed (#1838) 2025-01-04 12:45:16 +08:00
Mr. Chip
91876b42aa Fix: fix preg_match parameter#2 $subject is null deprecated issue (#1798) 2024-09-23 10:49:47 +08:00
Luffy
5783cb0d01 fix sendPingHandle warning (#1808) 2024-09-23 10:48:19 +08:00
ZShijun
87d479dd57 Update Login.php (#1804)
修复勾选下次自动登录,但重启浏览器不生效的bug
2024-09-11 10:59:32 +08:00
Luffy
ef9ef2ce45 Require PHP 7.4.0 or higher (#1785) 2024-07-24 15:51:19 +08:00
陆之岇
31f5192c9d Fix timezone error in XmlRpc (#1758)
Signed-off-by: Kraity <kraity@krait.cn>
2024-06-20 11:22:51 +08:00
Luffy
4ce9cdefc2 Fix TypeError: Typed property Typecho\Feed::$subTitle must be string (#1779) 2024-06-12 10:47:06 +08:00
Luffy
0b0476e565 Fix missing WidgetException error message (#1730) 2024-04-19 12:11:39 +08:00
Fen
71c6381b15 fix: nav menu active style (#1752) 2024-03-29 11:38:30 +08:00
Fen
fa107ffa51 update picocss to 2.0 (#1751) 2024-03-28 15:37:19 +08:00
Luffy
d84e261f7b Fix missing get date (#1740) 2024-02-28 10:57:47 +08:00
Luffy
3933a23ad7 Fix assign null to property Widget\Archive::$archiveKeywords (#1738)
* Fix assign null to property Widget\Archive::$archiveKeywords

* Fix
2024-02-26 11:52:17 +08:00
fen
0a40b1e7ee improve: comment color 2024-01-29 16:32:38 +08:00
Lu Fei
bda7541682 Limit build execution (#1723) 2024-01-29 12:05:30 +08:00
joyqi
f3a5336c1a Remove comment link if status is not approved (#1712)
* remove comment link if status is not approved

* fix stack

* fix: remove link in admin panel when comment status is not approved

* fix: comments page nav

* fix comment redirect url

* fix comment anchor

* fix waiting comment display

* fix: convert waiting to unapproved
2024-01-25 14:24:47 +08:00
Lu Fei
d1e961af90 Upgrade actions/checkout to v4 (#1718) 2024-01-24 02:18:19 +08:00
joyqi
e3bdef645d fix: remove unnecessary DOCTYPE tags (#1715) 2024-01-23 18:30:17 +08:00
joyqi
de53b64880 fix: remove special chars (#1716) 2024-01-23 18:29:59 +08:00
joyqi
d0b62eabe9 fix: xmlrpc message args (#1714) 2024-01-22 14:36:10 +08:00
Fen
99ffd36648 Fix/classic22 (#1708)
* fix: use prefers-color-scheme control dark mode

* update color
2024-01-15 10:56:47 +08:00
电脑星人
4028d7d160 fix: getHeader for Content-Type & Content-Length (#1703)
* fix: Request::getHeader for Content-Type & Content-Length

* fix: get content-type through native api

---------

Co-authored-by: joyqi <joyqi@users.noreply.github.com>
2024-01-13 22:11:38 +08:00
joyqi
a30a6c122d fix: choose the correct key when setting widget value (#1702) 2024-01-10 15:37:05 +08:00
Fen
0d28025bf4 update issue template 2024-01-10 12:58:20 +08:00
Fen
8b75782619 update issue template (#1700) 2024-01-10 12:45:24 +08:00
Fen
c5ab9295f0 Fix/classic 22 (#1698)
* style: move customize color to theme.css
2024-01-09 16:33:40 +08:00
Lu Fei
c816efa26e fix trim error (#1697) 2024-01-09 14:56:25 +08:00
joyqi
7115a30301 fix attachment handle (#1696)
* fix #1694

* fix array dump

* add toColumn method
2024-01-09 14:31:15 +08:00
LibXZR
db5d8694c4 Fix unable to show attachment parent in manage-medias (#1693) 2024-01-08 22:56:39 +08:00
Fen
2051c040ec Fix/classic 22 (#1690)
* fix: auto dark mode

* improve: pagenav style, theme color

* improve: color schema name

* fix: icon color

* improve: page navigation style
2024-01-07 13:47:59 +08:00
joyqi
13282b5b84 fix undefined array key (#1688)
* fix undefined array key

* fix: change security email
2024-01-07 11:38:39 +08:00
Fen
af281422d3 update theme classic-22 color schema (#1689)
* fix: auto dark mode

* improve: pagenav style, theme color

* improve: color schema name

* fix: icon color
2024-01-07 00:39:10 +08:00
LibXZR
68026e0fbc Fix unable to preview revisions (#1687)
* Fix unable to preview revisions

* Improve revision preview fix

Co-authored-by: joyqi <joyqi@users.noreply.github.com>

---------

Co-authored-by: joyqi <joyqi@users.noreply.github.com>
2024-01-06 23:33:11 +08:00
joyqi
a9fa990124 replace str compare (#1685) 2024-01-06 12:20:41 +08:00
Lu Fei
9635a7a0ba Optimize applySlug (#1684)
* Optimize applySlug

* optimize code

* fix: more rigorous judgment

* improve slug generating

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
2024-01-05 15:55:34 +08:00
Lu Fei
9396eef2f9 Remove useless code (#1683) 2024-01-05 11:27:13 +08:00
Fen
cec6b9c62b update theme classic-22 (#1682)
* Add feed widget

* add feed render

* Add CommentPage widget

* New theme (#1390)

* 调整忽略目录

* add theme

* fix theme scss build

Co-authored-by: fen <f3nb0x@gmail.com>

* s/is_writeable/is_writable/g

* New upgrade method

* merge new fixes from master

* add pgsql ssl mode support (ref #1600) (#1623)

* Feat/code refactor (#1626)

* remove all magic methods, add type for class properties

* refactor codes

* fix all

* refactor code

* fix type

* fix all

* fix request is method

* fix all

* fix router

* fix get page

* fix 1.3.0 upgrade

* [feat] support high resolution avatar

* fix types in i18n component

* Implement Ctrl+S or Command+S for save draft (#1628)

* Implement Ctrl+S or Command+S for save draft

* rename

* add Typecho.savePost

* fix upload file size

* add new uploader

* replace new uploader

* fix textarea change

* fix preview

* refactor post edit

* fix issue

* fix page edit

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* fix #1632

* Add svg to image types

* Feat/tree pages (#1646)

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Support IDN (#1629)

* Support IDN

* use js

* Optimize code

* Optimize code

* fix URL script

* remove unnecessary use

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* fix input element

* fix #1651, close #1653

* Use json instead of serialize (#1624)

* Use json instead of serialize

* Fix Upgrade code

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Fix typo

* remove proxy methods

* remove unnecessary useage

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* Fix Prevent XSS vulnerability in default theme (#1654)

* Fix Prevent XSS vulnerability in default theme

* Update var/Typecho/Db/Adapter/Pdo.php

* fix the getter

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* add throwCallback to widget response

* fix: cut down fields when selecting recent posts

* fix typo errors

* fix typo errors

* fix http client cookie

* add throw finish

* fix theme lang

* fix default theme

* fix query

* add open graph and twitter card support
add canonical link

* fix canonical link meta

* fix theme classic-22

* remove unnecessary scss file when packaging

* init plugin signal

* improve: remove feather-icon js file

* fix: typo

* improve: post detail layout

* fix tags saving

* improve: nav search

* fix: theme screenshot

* fix: theme page layout

* remove php 7.2/7.3 env

* feat: pull request auto merge

* fix permission

* improve: comment style

* fix: search result

* improve: show site description in homepage title

---------

Co-authored-by: joyqi <magike.net@gmail.com>
Co-authored-by: joyqi <joyqi@users.noreply.github.com>
Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: Lu Fei <52o@qq52o.cn>
2024-01-05 00:11:38 +08:00
joyqi
f23e825b95 fix router 2024-01-04 23:13:16 +08:00
joyqi
1c3b86fc22 fix #1679 (#1680)
Detect the insertion point of reply form automatically.
2024-01-04 22:47:15 +08:00
Fen
540dbb3b21 Create SECURITY.md 2024-01-04 17:12:29 +08:00
joyqi
81ad2232bf fix #1671 (#1678) 2024-01-04 11:13:36 +08:00
Lu Fei
d520a556cf fix style error for code (#1677) 2024-01-02 13:47:29 +08:00
joyqi
77aebcbd0e fix #1674 (#1676) 2024-01-02 11:16:44 +08:00
LibXZR
f3299ecb8a Fix broken link when paging by category or tags (#1673) 2024-01-01 18:34:20 +08:00
joyqi
b88a733dc0 Dev (#1670)
* Add feed widget

* add feed render

* Add CommentPage widget

* New theme (#1390)

* 调整忽略目录

* add theme

* fix theme scss build

Co-authored-by: fen <f3nb0x@gmail.com>

* s/is_writeable/is_writable/g

* New upgrade method

* merge new fixes from master

* add pgsql ssl mode support (ref #1600) (#1623)

* Feat/code refactor (#1626)

* remove all magic methods, add type for class properties

* refactor codes

* fix all

* refactor code

* fix type

* fix all

* fix request is method

* fix all

* fix router

* fix get page

* fix 1.3.0 upgrade

* [feat] support high resolution avatar

* fix types in i18n component

* Implement Ctrl+S or Command+S for save draft (#1628)

* Implement Ctrl+S or Command+S for save draft

* rename

* add Typecho.savePost

* fix upload file size

* add new uploader

* replace new uploader

* fix textarea change

* fix preview

* refactor post edit

* fix issue

* fix page edit

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* fix #1632

* Add svg to image types

* Feat/tree pages (#1646)

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Support IDN (#1629)

* Support IDN

* use js

* Optimize code

* Optimize code

* fix URL script

* remove unnecessary use

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* fix input element

* fix #1651, close #1653

* Use json instead of serialize (#1624)

* Use json instead of serialize

* Fix Upgrade code

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Fix typo

* remove proxy methods

* remove unnecessary useage

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* Fix Prevent XSS vulnerability in default theme (#1654)

* Fix Prevent XSS vulnerability in default theme

* Update var/Typecho/Db/Adapter/Pdo.php

* fix the getter

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* add throwCallback to widget response

* fix: cut down fields when selecting recent posts

* fix typo errors

* fix typo errors

* fix http client cookie

* add throw finish

* fix theme lang

* fix default theme

* fix query

* add open graph and twitter card support
add canonical link

* fix canonical link meta

* fix theme classic-22

* remove unnecessary scss file when packaging

* init plugin signal

* improve: remove feather-icon js file

* fix: typo

* improve: post detail layout

* fix tags saving

* improve: nav search

* fix: theme screenshot

* fix: theme page layout

* remove php 7.2/7.3 env

* feat: pull request auto merge

* fix permission

---------

Co-authored-by: fen <f3nb0x@gmail.com>
Co-authored-by: Lu Fei <52o@qq52o.cn>
2023-12-31 17:13:56 +08:00
jrotty
746667a8e6 删除多余无用js (#1668)
看了下默认主题没有引用任何js,这个应该是多余的
2023-12-31 17:05:45 +08:00
joyqi
6232de74e9 Merge pull request branch automatically (#1669)
* Add feed widget

* add feed render

* Add CommentPage widget

* New theme (#1390)

* 调整忽略目录

* add theme

* fix theme scss build

Co-authored-by: fen <f3nb0x@gmail.com>

* s/is_writeable/is_writable/g

* New upgrade method

* merge new fixes from master

* add pgsql ssl mode support (ref #1600) (#1623)

* Feat/code refactor (#1626)

* remove all magic methods, add type for class properties

* refactor codes

* fix all

* refactor code

* fix type

* fix all

* fix request is method

* fix all

* fix router

* fix get page

* fix 1.3.0 upgrade

* [feat] support high resolution avatar

* fix types in i18n component

* Implement Ctrl+S or Command+S for save draft (#1628)

* Implement Ctrl+S or Command+S for save draft

* rename

* add Typecho.savePost

* fix upload file size

* add new uploader

* replace new uploader

* fix textarea change

* fix preview

* refactor post edit

* fix issue

* fix page edit

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* fix #1632

* Add svg to image types

* Feat/tree pages (#1646)

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Support IDN (#1629)

* Support IDN

* use js

* Optimize code

* Optimize code

* fix URL script

* remove unnecessary use

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* fix input element

* fix #1651, close #1653

* Use json instead of serialize (#1624)

* Use json instead of serialize

* Fix Upgrade code

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Fix typo

* remove proxy methods

* remove unnecessary useage

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* Fix Prevent XSS vulnerability in default theme (#1654)

* Fix Prevent XSS vulnerability in default theme

* Update var/Typecho/Db/Adapter/Pdo.php

* fix the getter

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* add throwCallback to widget response

* fix: cut down fields when selecting recent posts

* fix typo errors

* fix typo errors

* fix http client cookie

* add throw finish

* fix theme lang

* fix default theme

* fix query

* add open graph and twitter card support
add canonical link

* fix canonical link meta

* fix theme classic-22

* remove unnecessary scss file when packaging

* init plugin signal

* improve: remove feather-icon js file

* fix: typo

* improve: post detail layout

* fix tags saving

* improve: nav search

* fix: theme screenshot

* fix: theme page layout

* remove php 7.2/7.3 env

* feat: pull request auto merge

---------

Co-authored-by: fen <f3nb0x@gmail.com>
Co-authored-by: Lu Fei <52o@qq52o.cn>
2023-12-31 17:04:45 +08:00
Lu Fei
e306960db4 Fix installation failure (#1664)
* Fix installation failure

* fix missing secret

* Apply suggestions from code review
2023-12-31 16:10:05 +08:00
joyqi
3caebb3b20 v1.3.0 (#1661)
* Add feed widget

* add feed render

* Add CommentPage widget

* New theme (#1390)

* 调整忽略目录

* add theme

* fix theme scss build

Co-authored-by: fen <f3nb0x@gmail.com>

* s/is_writeable/is_writable/g

* New upgrade method

* merge new fixes from master

* add pgsql ssl mode support (ref #1600) (#1623)

* Feat/code refactor (#1626)

* remove all magic methods, add type for class properties

* refactor codes

* fix all

* refactor code

* fix type

* fix all

* fix request is method

* fix all

* fix router

* fix get page

* fix 1.3.0 upgrade

* [feat] support high resolution avatar

* fix types in i18n component

* Implement Ctrl+S or Command+S for save draft (#1628)

* Implement Ctrl+S or Command+S for save draft

* rename

* add Typecho.savePost

* fix upload file size

* add new uploader

* replace new uploader

* fix textarea change

* fix preview

* refactor post edit

* fix issue

* fix page edit

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* fix #1632

* Add svg to image types

* Feat/tree pages (#1646)

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Support IDN (#1629)

* Support IDN

* use js

* Optimize code

* Optimize code

* fix URL script

* remove unnecessary use

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* fix input element

* fix #1651, close #1653

* Use json instead of serialize (#1624)

* Use json instead of serialize

* Fix Upgrade code

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Fix typo

* remove proxy methods

* remove unnecessary useage

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* Fix Prevent XSS vulnerability in default theme (#1654)

* Fix Prevent XSS vulnerability in default theme

* Update var/Typecho/Db/Adapter/Pdo.php

* fix the getter

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* add throwCallback to widget response

* fix: cut down fields when selecting recent posts

* fix typo errors

* fix typo errors

* fix http client cookie

* add throw finish

* fix theme lang

* fix default theme

* fix query

* add open graph and twitter card support
add canonical link

* fix canonical link meta

* fix theme classic-22

* remove unnecessary scss file when packaging

* init plugin signal

* improve: remove feather-icon js file

* fix: typo

* improve: post detail layout

* fix tags saving

* improve: nav search

* fix: theme screenshot

* fix: theme page layout

* remove php 7.2/7.3 env

---------

Co-authored-by: fen <f3nb0x@gmail.com>
Co-authored-by: Lu Fei <52o@qq52o.cn>
2023-12-30 23:02:25 +08:00
insomnux
43c54328f7 gettext for installation comment (#1643)
Co-authored-by: insomnux <insomnux@insomnus.info>
2023-10-31 11:30:54 +08:00
joyqi
99212ec787 fix #1635 (#1636) 2023-10-03 11:14:04 +08:00
Lu Fei
5f52c1e25b Fix null argument issue (#1633) 2023-10-03 11:12:46 +08:00
jrotty
272fc8b3e1 增加邮箱也可以登陆的提示 (#1631)
😭用了八年,今天翻代码才知道也可以用邮箱登陆
2023-09-29 15:12:11 +08:00
Losses Don
e143be0036 fix: Fix #1597 (#1598) 2023-09-22 10:54:38 +08:00
joyqi
91ae56484d fix the source to get content type (#1622) 2023-09-22 10:50:39 +08:00
Lu Fei
9910a9cddc Optimize checkVersion,feed code (#1605) 2023-09-22 10:49:51 +08:00
Jealous
666619538a Fix typo (#1612) 2023-09-21 22:48:27 +08:00
Kent Liao
9d1b01a873 fix: adding checkbox options after theme initialization cannot be saved. (#1591)
* fix: adding checkbox options after theme initialization cannot be saved.

* chore: Use isset to determine if an option exists
2023-06-14 08:58:27 +08:00
logdd
206880ba71 重复执行判断的优化 (#1586)
使用$isNamespace变量,避免重复判断
2023-06-05 15:15:24 +08:00
joyqi
c1753aa04e improve release ci, upload built asset after new release published. (#1576) 2023-05-17 11:35:18 +08:00
joyqi
6f19a24aa3 fix #1574 (#1575)
* split multiple values

* add a new field type 'json' to handle complex situation

* fix json input display
2023-05-16 21:45:41 +08:00
沈唁
c725fec12e Add a prompt message for manual database creation (#1348)
* Optimize for no database during install

* change tips
2023-05-16 14:33:26 +08:00
joyqi
596d117210 fix: when setting CheckBox's default value to null [ref #1568] 2023-05-16 12:33:49 +08:00
joyqi
0433a11c0a escape mail string before output 2023-05-15 22:35:25 +08:00
joyqi
98e4c1d16d fix url validate 2023-05-15 21:44:12 +08:00
joyqi
7a41f0d013 fix email validate 2023-05-15 19:55:36 +08:00
Ryan Lieu
c9de1b3b01 fix php 8.1 Deprecated: htmlspecialchars(): Passing null to parameter #1 (#1570)
* Fix multiple calls returning the same object

* fix: strtolower() passing null to parameter #1 ($string) of type string is deprecated

* fix: php 8.1 Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated
2023-05-15 18:30:44 +08:00
Patrick SAMA
83d4d020ed Fix an XSS vulnerability in v1.2.1-rc (#1561)
* fix #1560

* Update var/Typecho/Validate.php

Co-authored-by: 沈唁 <52o@qq52o.cn>

---------

Co-authored-by: joyqi <joyqi@users.noreply.github.com>
Co-authored-by: 沈唁 <52o@qq52o.cn>
2023-05-15 18:29:47 +08:00
Ryan Lieu
01100c9a4a Fix: php 8.1 strtolower not allow null value (#1559) 2023-04-14 11:45:09 +08:00
沈唁
daef17d7eb Support ssl for pdo_mysql and mysqli (#1525)
* Support ssl for pdo_mysql and mysqli

* Improve config name for mysql ssl mode, and fix some minor bugs.

* Fix typo

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
2023-03-29 14:33:23 +08:00
joyqi
65f5974e17 Replace the protocol of backend remote checking url from http to https. 2023-03-28 12:07:33 +08:00
Zero King
f6e1232db8 Use https links (#1280) 2023-03-28 11:57:45 +08:00
joyqi
b989459d87 fix #1545 and close #1547 2023-03-28 11:36:01 +08:00
joyqi
a609b149e9 fix #1539 2023-03-03 16:37:32 +08:00
joyqi
f9ede542c9 fix #1535 2023-02-21 17:43:20 +08:00
沈唁
16d21f03ef Fix htmlspecialchars error for feed (#1522) 2023-01-11 00:45:28 +08:00
Zero King
8437eac420 Fix unsafe use of jQuery .html() (#1382) 2022-10-29 23:54:13 +08:00
joyqi
f0bf9d770d update readme 2022-10-25 14:53:09 +08:00
沈唁
e05ebe442e Fix #1495 (#1496)
Argument 1 passed to Utils\AutoP::parse() must be of the type string, null given
2022-09-22 10:25:18 +08:00
沈唁
17d9dcfa17 Fix comments feed jump error (#1491) 2022-08-15 07:24:43 +08:00
沈唁
2014be4cd3 Adjust style of edit comments (#1483)
* Adjust style of edit comments

Fix #1481

* update

* update
2022-08-01 14:56:22 +08:00
沈唁
d15fc14463 Fix use SQLite error of windows install (#1471) 2022-07-20 00:20:25 +08:00
Ryan Lieu
f07b57fe20 Fix multiple calls returning the same object (#1478) 2022-07-15 11:19:18 +08:00
沈唁
c03ee2c8be Fix the error of getting request parameters (#1464) 2022-06-21 13:59:53 +08:00
Kane
4095850140 Minor update (#1460)
- 后台上传设置增加 avif 类型
- 后台 Avatar 头像支持原生懒加载
2022-06-14 18:57:07 +08:00
Kane
7f7b24d28f Minor update (#1451)
* Update

- 更新 Windows 和 Linux 系统中文本编辑器样式问题(为代码块中添加中文后备字体修正样式)

* Update

- 缩略图支持识别 avif 图片(具体可参考https://en.wikipedia.org/wiki/AVIF
2022-06-07 18:08:24 +08:00
joyqi
1d0e253281 Fix page draft publish 2022-06-01 23:50:36 +08:00
沈唁
88c3bfe13f Fix #1449 (#1450) 2022-05-30 11:11:44 +08:00
沈唁
59a5c8d14d Fix category creation error when using xmlrpc (#1443)
* Fix category creation error when using xmlrpc

* Add use Typecho\Request
2022-05-23 10:44:59 +08:00
joyqi
3119c05e2c fix #1441, fix #1442 2022-05-17 10:24:56 +08:00
joyqi
05e20c0ae5 Fix themeUrl format 2022-05-13 00:46:12 +08:00
沈唁
7279d4832d Fix missing change themeUrl (#1431)
* Fix missing change themeUrl

* Use options themeUrl method
2022-05-13 00:26:10 +08:00
沈唁
ac33000ad0 Add admin/footer.php begin plugin (#1426) 2022-05-07 16:33:00 +08:00
MBRjun Duplicate
02937dc51c Fix QUIC/https Mixed Content (#1423) 2022-05-04 09:31:59 +08:00
jrotty
437d296af5 修复管理员进入其他用户文章列表时显示所有文章的bug (#1415)
* 修复管理员进入其他用户文章列表时显示所有文章的bug

bug描述:当管理员在文章管理页面,点击所有查看所有文章后,再通过这个页面进入作者文章管理页面时,仍会显示所有文章而不是当前作者的文章

* Update manage-users.php

* Fix missing manage-posts

Co-authored-by: sy-records <52o@qq52o.cn>
2022-04-29 10:53:05 +08:00
沈唁
f31e6daf7b Fix notice not clear (#1416) 2022-04-26 10:29:26 +08:00
jrotty
f8a9d95e43 修正注释 (#1411)
* 修正注释

* 修正注释
2022-04-23 18:00:02 +08:00
jrotty
0fbb1aaea5 模板缩略图支持识别webp图片后缀 (#1403)
* 模板缩略图支持识别webp图片后缀

* Update Contents.php

Co-authored-by: 沈唁 <52o@qq52o.cn>
2022-04-15 13:51:06 +08:00
Valpha
9fd02529b1 Update write-js.php (#1400)
Add 'allow-same-origin' into sandbox's attrs to fix that the article preview page does not match the real page.
2022-04-15 13:50:13 +08:00
沈唁
3512fd41bf Enhancement of Typecho\Cookie (#1399) 2022-04-14 15:49:04 +08:00
joyqi
997aa607ac fix words 2022-04-07 11:28:28 +08:00
沈唁
3b03e0267b Update admin welcome tip (#1389) 2022-04-07 11:26:02 +08:00
joyqi
61606a9069 fix #1380 2022-04-05 22:53:39 +08:00
joyqi
34e5bf2861 fix #1375 2022-04-04 00:01:33 +08:00
沈唁
c78f7fda68 Fix pgsql reset id error (#1369) 2022-04-02 21:27:31 +08:00
joyqi
7ebfe82de1 fix #1361 2022-04-02 18:10:28 +08:00
joyqi
004db7c056 Move language build trigger from workflows/dev to workflows/release. 2022-04-02 16:41:37 +08:00
joyqi
d4068b1661 fix #1363, close #1364
Add json request & response. Perform async service via json request.
2022-04-02 15:33:17 +08:00
joyqi
d77a1ecad7 Delete config.inc.sqlite.php 2022-04-01 16:55:08 +08:00
joyqi
ded268ef59 Pr/1344 (#1360)
* Add missing theme action

* Fix typo

* Optimize code

* Optimize code

* Update themes.php

* Simpler missing theme judgement

Co-authored-by: sy-records <52o@qq52o.cn>
2022-04-01 16:50:23 +08:00
joyqi
142a615feb Merge branch 'master' of github.com:typecho/typecho 2022-04-01 15:25:28 +08:00
joyqi
c30b67d18d Update .gitignore
update gitignore
2022-04-01 15:25:10 +08:00
毛线
2db893e802 Update install.php (#1357)
修复宝塔面板的网站目录带.导致db路径校验不通过的问题
2022-04-01 14:07:08 +08:00
沈唁
2f3e15dfb8 Fix checkVersion (#1356) 2022-04-01 11:12:54 +08:00
沈唁
4be93f2741 Fix missing mysqli_connect_errno (#1346) 2022-03-28 12:11:24 +08:00
joyqi
6100695d87 fix db exception 2022-03-25 15:31:57 +08:00
fen
0bdf8721e1 add ignore 2022-03-25 12:08:22 +08:00
沈唁
ce7af58367 Optimize code (#1342) 2022-03-24 17:46:03 +08:00
joyqi
1b673e06ff fix typecho/Dockerfile#9 2022-03-22 14:24:14 +08:00
joyqi
0edb48fae0 fix #1335, close #1337 2022-03-16 21:05:22 +08:00
沈唁
17fcb2f08b Fix undefined Typecho\Db\Adapter_Exception (#1334) 2022-03-15 16:09:32 +08:00
joyqi
5f943d48b5 fix #1329 2022-02-25 21:16:12 +08:00
joyqi
b23277267a fix #1328 2022-02-24 23:21:35 +08:00
沈唁
b0d78a81dc Fix #1326 (#1327) 2022-02-21 21:51:13 +08:00
沈唁
f34d14280d Fix compatibility with PHP 8.1 (#1324)
* Fix compatibility with PHP 8.1

PHP Deprecated:  htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in typecho/var/Widget/Archive.php on line 1292

* Fix login

* Fix write

* Fix manage

* Fix PHP Deprecated
2022-02-15 11:10:47 +08:00
沈唁
13dc5e87dd Fix #1322 (#1323)
Great work!
2022-02-15 11:10:15 +08:00
沈唁
0b021e5e7d Fix broken extends.typecho.org link (#1315)
close #857
2022-02-09 11:41:35 +08:00
joyqi
00c75d2f75 fix version compare 2022-01-30 00:30:28 +08:00
joyqi
1eedc481ad fix #1295, ref #1297 2022-01-29 17:46:48 +08:00
joyqi
75899e287d fix #1268 2022-01-28 23:58:31 +08:00
jiayx
047bd17f19 Fixes for PHP 8.1 compatibility (#1293)
* Fixes for PHP 8.1 compatibility

* Fixes for PHP 8.1 compatibility

* 优化写法

* remove mixed type

* fix nullable column

* fix query filter

* recover

* recover fileds

* recover

* Update Text.php

* Update Text.php

Co-authored-by: joyqi <joyqi@users.noreply.github.com>
2022-01-28 23:51:24 +08:00
joyqi
9c075dcdf0 fix #1279 2022-01-13 14:04:58 +08:00
joyqi
157fc05265 fix #1268 2021-12-13 11:58:35 +08:00
joyqi
c047669900 fix #1257 2021-12-06 22:09:17 +08:00
joyqi
eee0228fed Refactor HttpClient, fix #1246 2021-11-18 00:20:24 +08:00
joyqi
389b46635e fix client 2021-11-17 18:34:01 +08:00
joyqi
919911e288 fix redirect 2021-11-17 00:33:05 +08:00
joyqi
dd4bf889de fix #1222 2021-11-04 16:37:29 +08:00
joyqi
0dcf45a152 fix #1220 2021-10-30 00:02:41 +08:00
joyqi
ceaa545c7d fix #1212 2021-10-28 19:53:18 +08:00
joyqi
01d9d0c3f5 fix #1207 2021-10-28 12:04:00 +08:00
joyqi
6b46dd9c50 Merge branch 'master' of github.com:typecho/typecho 2021-10-21 22:09:05 +08:00
joyqi
cb4457ab52 fix #1201 2021-10-21 22:08:53 +08:00
joyqi
8a57b91343 fix #1203 2021-10-21 18:49:05 +08:00
joyqi
c66b6e20ec fix #1187 2021-10-21 11:10:34 +08:00
joyqi
b33a9c4d02 ref https://github.com/typecho/Dockerfile/issues/1 2021-10-13 18:34:46 +08:00
joyqi
cac1c650a1 fix #1196 2021-10-13 16:31:15 +08:00
joyqi
42e192340d fix #1194 2021-10-13 15:50:40 +08:00
joyqi
b677f7db92 Merge branch 'master' of github.com:typecho/typecho 2021-10-13 14:33:43 +08:00
joyqi
2fbc56dead ref https://github.com/typecho/Dockerfile/issues/1 2021-10-13 14:33:28 +08:00
joyqi
d174cc5732 update hyperdown 2021-09-30 01:06:14 +08:00
joyqi
5557f6dd91 fix clear 2021-09-29 17:10:34 +08:00
joyqi
42fe6f7bf5 fix #1191 2021-09-26 16:15:17 +08:00
joyqi
1f1019ba5b fix #1189 2021-09-23 11:29:10 +08:00
joyqi
13d18e02cc Create CODE_OF_CONDUCT.md 2021-09-17 21:59:56 +08:00
joyqi
e46acd815d improve cli install 2021-09-17 15:15:54 +08:00
joyqi
432b69f70d fix install detect & error display 2021-09-17 15:06:05 +08:00
joyqi
0e750771ae fix service 2021-09-16 21:54:49 +08:00
joyqi
fc9aaf66f3 Use TypechoPlugin\ for plugin namespace 2021-09-16 17:53:59 +08:00
joyqi
ec495d7e24 Add magic method to native request object 2021-09-16 17:05:43 +08:00
joyqi
f6b02ebe24 fix port number 2021-09-16 15:42:17 +08:00
joyqi
64b8e68688 fix #1178, change directory permission from 0777 to 0755 2021-09-15 14:59:08 +08:00
joyqi
4e5b88821d fix #1179 2021-09-15 14:33:23 +08:00
joyqi
a003cffbbb fix radio & checkbox vertical alignment. 2021-09-15 14:15:06 +08:00
joyqi
7ef5fcabd5 fix pingback & request 2021-09-15 01:25:36 +08:00
joyqi
3c4a0022c3 fix pingback 2021-09-15 00:31:13 +08:00
joyqi
780c3b61f4 fix ci build 2021-09-14 22:21:51 +08:00
joyqi
1d21ecac16 fix zip 2021-09-14 21:48:43 +08:00
joyqi
2d777ec061 fix tar 2021-09-14 21:39:06 +08:00
joyqi
5d20d57be9 fix #1173 2021-09-14 00:24:56 +08:00
joyqi
3f14d6e138 fix 2021-09-12 18:09:37 +08:00
joyqi
1ee18ad532 fix #1160 2021-09-11 01:06:54 +08:00
joyqi
419183ae2f fix #1167 2021-09-10 23:09:59 +08:00
joyqi
0916631ae2 fix #1165 2021-09-10 17:36:52 +08:00
joyqi
4186cdec6a fix #1164 2021-09-10 14:52:55 +08:00
joyqi
cbb270ea89 fix backup recover error 2021-09-10 11:47:55 +08:00
joyqi
d839f390ee fix #1163, fix #1164 2021-09-10 11:26:04 +08:00
joyqi
26e8077e0a fix alias 2021-09-10 02:28:15 +08:00
joyqi
b5167dbe5d fix #1158 2021-09-10 02:22:45 +08:00
joyqi
a1bf3d037b fix #1162 2021-09-09 20:18:11 +08:00
joyqi
ed30a99655 fix request response error 2021-09-09 20:08:04 +08:00
joyqi
bf2cb07e4b fix #1160 2021-09-09 18:20:30 +08:00
joyqi
729dcf729a fix #1160 2021-09-09 17:45:15 +08:00
joyqi
58cb9105d4 fix #1157 2021-09-09 15:06:05 +08:00
joyqi
eb77897ab6 fix #1159 2021-09-09 14:09:19 +08:00
joyqi
4ad930a31d Merge branch 'master' of github.com:typecho/typecho 2021-09-09 11:41:39 +08:00
joyqi
fa222ba7a2 fix #1157 2021-09-09 11:41:17 +08:00
joyqi
519e84e74c fix #1156 2021-09-09 00:16:07 +08:00
joyqi
57106d85c9 fix requestUri 2021-09-08 22:33:26 +08:00
joyqi
a4883be588 fix #1155 2021-09-08 22:18:11 +08:00
joyqi
96eb56fc35 fix #1154 2021-09-08 21:47:54 +08:00
joyqi
a3d698c09e fix actions 2021-09-08 16:36:56 +08:00
joyqi
9bd4eaeae8 fix release action 2021-09-08 16:17:55 +08:00
joyqi
a31da6880d fix destroy bug 2021-09-07 16:56:08 +08:00
joyqi
0759a9414a fix #1147 2021-09-07 16:31:06 +08:00
joyqi
ee00fc567f fix #1152 2021-09-07 15:59:09 +08:00
joyqi
5303124431 Merge pull request #1151 from typecho/dev
Dev
2021-09-07 11:00:58 +08:00
joyqi
74b0f45a72 fix format 2021-09-06 14:16:21 +08:00
joyqi
0f3f15c0ca fix titile 2021-09-06 14:00:39 +08:00
joyqi
cbfe180d8b fix rss 2021-09-06 00:37:59 +08:00
joyqi
d24a16ad23 fix sandbox 2021-09-05 11:09:06 +08:00
joyqi
6123f3ae62 fix sandbox 2021-09-05 10:47:29 +08:00
joyqi
89649522c7 fix sandbox 2021-09-04 21:27:57 +08:00
joyqi
675efe1e43 add sandbox 2021-09-04 21:12:14 +08:00
joyqi
f40c5c178e fix delete 2021-09-03 12:40:02 +08:00
joyqi
5a2833c5aa fix xmlrpc 2021-09-03 12:22:22 +08:00
joyqi
c279ef1443 fix xmlrpc 2021-09-03 02:27:52 +08:00
joyqi
6cedf6a0a1 fix xmlrpc 2021-09-03 00:15:22 +08:00
joyqi
7068b2bbe1 Refactor method pluginDIr 2021-09-02 17:55:41 +08:00
joyqi
4791cd978e fix bug 2021-09-02 16:13:32 +08:00
joyqi
403f96fdc0 Change plugin version dependence keyword form dependence to since 2021-09-02 15:30:26 +08:00
joyqi
86587d40ce fix options 2021-09-02 11:58:02 +08:00
joyqi
7bd37f7d8c fix options 2021-09-02 11:34:12 +08:00
joyqi
ecd21c2557 fix plugin name 2021-09-01 22:52:02 +08:00
joyqi
50dea3fc24 fix plugin namespace 2021-09-01 18:45:59 +08:00
joyqi
7db5f3c873 change all 2021-09-01 18:27:03 +08:00
joyqi
4f13adcadd replace theme and plugin file 2021-09-01 17:21:58 +08:00
joyqi
ba0bfd3551 replace with new namespace rule 2021-09-01 17:08:57 +08:00
joyqi
2fad7cc398 fix attr 2021-09-01 13:49:32 +08:00
joyqi
49eed7b437 fix xmlrpc 2021-09-01 00:04:05 +08:00
joyqi
d72d4ea2ab finish xmlrpc 2021-08-31 18:25:49 +08:00
joyqi
7ca696ce90 fix all 2021-08-31 01:52:30 +08:00
joyqi
806409496a fix xmlrpc 2021-08-31 00:18:56 +08:00
joyqi
e2ca6a1fa7 fix 2021-08-30 17:45:18 +08:00
joyqi
e15c2966a9 still working on it 2021-08-30 14:52:52 +08:00
joyqi
93b5656109 fix action 2021-08-27 18:27:21 +08:00
joyqi
539ef5e111 still working on it 2021-08-27 18:06:57 +08:00
joyqi
7a1b74b351 still working on it 2021-08-26 22:19:04 +08:00
joyqi
540fba3122 fix class rewrite 2021-08-26 18:48:04 +08:00
joyqi
28f687e7fe Remove some unnecessary method. 2021-08-26 18:25:43 +08:00
joyqi
91a970521c New context layer for widget. Improve backup performance. 2021-08-26 15:00:38 +08:00
joyqi
926ec3e117 fix bug 2021-08-24 18:47:21 +08:00
joyqi
23d52d44a1 refactor code 2021-08-24 18:30:04 +08:00
joyqi
cf9776ee43 replace underscore with backslash 2021-08-24 14:19:14 +08:00
joyqi
a2e784113a new request wrapper 2021-08-24 14:08:58 +08:00
joyqi
38184ba5ba fix pgsql 2021-08-24 02:04:55 +08:00
joyqi
c422952c89 fix pgsql 2021-08-24 01:30:05 +08:00
joyqi
75672fe259 fix all 2021-08-23 18:43:32 +08:00
joyqi
82fe09cf52 Finish refactoring widget helper 2021-08-23 12:32:18 +08:00
joyqi
b0df985d66 Refactor codes 2021-08-22 23:27:07 +08:00
joyqi
09a320bf5d fix #1139 2021-08-22 19:32:11 +08:00
joyqi
5163c43610 remove old file 2021-08-22 01:27:32 +08:00
joyqi
e20e6804e9 Finish router and plugin refactoring 2021-08-22 01:27:04 +08:00
joyqi
eeb893485b Finish http client refactoring 2021-08-21 23:11:10 +08:00
joyqi
80746465c7 Merge commit 'c84fa39c4f95be47bed6ee418c99b7000f020240' into dev 2021-08-21 21:23:32 +08:00
joyqi
0e4391006c Still working on namespace 2021-08-21 21:22:43 +08:00
joyqi
c84fa39c4f fix #1138 2021-08-21 21:19:42 +08:00
joyqi
687a4c8e26 Refactor autoload, use namespace 2021-08-20 18:34:59 +08:00
joyqi
92cb7834e2 Merge commit '88fff899b85bf7ef218fee3085c8792f204f9dc5' into dev 2021-08-20 17:54:02 +08:00
joyqi
88fff899b8 Update install.php 2021-08-20 17:53:02 +08:00
joyqi
5d2aef0dac Refactor Db class and still working on it. 2021-08-20 16:44:17 +08:00
joyqi
75d5677d7d Make API Typecho_Common::arrayFlatten deprecated, please use array_column instead. 2021-08-20 16:42:40 +08:00
joyqi
687ab6260a change error handler 2021-08-20 16:30:16 +08:00
joyqi
30baad977c Link build actions 2021-08-20 15:50:05 +08:00
joyqi
c8c4d9e079 Use WORKFLOW_TOKEN for trigger 2021-08-20 15:21:15 +08:00
joyqi
92debef3e3 Merge pull request #1137 from typecho/dev
Merge from branch dev
2021-08-20 15:05:06 +08:00
joyqi
1c189588db Reformat code 2021-08-20 15:03:45 +08:00
joyqi
0177a0557a Split test and build stage 2021-08-20 12:17:47 +08:00
joyqi
6855e9f1f3 with access token 2021-08-20 11:55:51 +08:00
joyqi
478ec92491 Make widget's property sequence and length readonly. 2021-08-20 11:27:03 +08:00
joyqi
256fff6b24 change token 2021-08-20 11:21:35 +08:00
joyqi
31ed159312 Merge branch 'dev' of github.com:typecho/typecho into dev 2021-08-20 11:20:54 +08:00
joyqi
b3b9255c69 fix #1134
fix #1135
fix #1136
2021-08-20 11:15:11 +08:00
joyqi
22cadcc884 add trigger 2021-08-20 01:08:37 +08:00
joyqi
df854a3bf0 Remove minor version 2021-08-20 00:58:22 +08:00
joyqi
5b58d71b61 Merge commit 'fc0485c891849706b2b60c67e52fe5638a7e707a' into dev
* commit 'fc0485c891849706b2b60c67e52fe5638a7e707a':
  Update Typecho-dev-Ci.yml
  Update Typecho-dev-Ci.yml
  Update Typecho-dev-Ci.yml
  Update Typecho-dev-Ci.yml
2021-08-20 00:57:39 +08:00
joyqi
fc0485c891 Update Typecho-dev-Ci.yml 2021-08-19 18:20:27 +08:00
joyqi
78a4cc9f84 Update Typecho-dev-Ci.yml 2021-08-19 17:58:47 +08:00
joyqi
29cf8a070d Update Typecho-dev-Ci.yml 2021-08-19 17:57:44 +08:00
joyqi
45c8b22ba7 Update Typecho-dev-Ci.yml 2021-08-19 16:58:12 +08:00
joyqi
d0cedde7c0 change build target 2021-08-19 16:56:59 +08:00
joyqi
efc5bf5c51 update hyperdown 2021-08-19 15:56:42 +08:00
joyqi
24bd3ab367 Redirect to siteUrl if installation finished 2021-08-19 11:15:53 +08:00
joyqi
954e710013 remove func_get_args 2021-08-18 23:16:08 +08:00
joyqi
4b97110087 fix stack 2021-08-18 22:55:32 +08:00
joyqi
3d0b5d5f6c reformat code 2021-08-18 22:29:34 +08:00
joyqi
44aef6c707 reformat code 2021-08-18 18:41:39 +08:00
joyqi
8f61e2155c Merge pull request #1131 from typecho/dev
Say goodbye to old install script. Now we support install from cli, and ready for container using.
2021-08-18 16:19:57 +08:00
joyqi
467471c9c3 finish install 2021-08-18 16:09:22 +08:00
joyqi
423c99f3bd Remove isFlash detector 2021-08-18 11:45:19 +08:00
joyqi
7f3cd2b9e8 Remove isAppEngine detector 2021-08-18 11:41:52 +08:00
joyqi
12bd32babf fix install 2021-08-18 00:47:34 +08:00
joyqi
3dabb7b8d8 specify node version 2021-08-18 00:43:32 +08:00
joyqi
10dd9344b8 update node 2021-08-18 00:42:11 +08:00
joyqi
3ad7b06c6f fix cli install 2021-08-18 00:41:48 +08:00
joyqi
e157b47336 fix install cli mode 2021-08-17 22:44:06 +08:00
joyqi
63dc87e7e3 fix cli 2021-08-17 18:39:46 +08:00
joyqi
2731e34db0 fix install 2021-08-17 18:36:54 +08:00
joyqi
0d4299d99e update install 2021-08-17 01:53:47 +08:00
joyqi
bac7340c2a improve installation 2021-08-16 18:34:25 +08:00
joyqi
21a57903a9 update build file 2021-08-08 13:00:01 +08:00
joyqi
39fcd8d513 update hyperdown 2021-08-08 12:47:16 +08:00
joyqi
371b88f9f8 fix simpleLogin 2021-08-06 17:23:42 +08:00
joyqi
a1168057a8 fix #1124
Extend usage scope of method simpleLogin.
2021-08-05 15:13:41 +08:00
joyqi
a38571bc64 Merge pull request #1119 from FlyingSky-CN/patch-1
fix #1118;
2021-07-28 22:21:07 +08:00
FlyingSky
79179fb65a fix #1118;
@see #1118
2021-07-23 17:23:36 +08:00
joyqi
27e6801e15 update hyperdown 2021-07-21 14:44:28 +08:00
joyqi
3dd592ae59 update hyperdown 2021-07-20 16:12:32 +08:00
joyqi
454302b3a1 update hyperdown 2021-07-12 10:31:54 +08:00
joyqi
3da4d660ec update hyperdown 2021-07-05 15:44:33 +08:00
joyqi
cb4778d6c4 update hyperdown 2021-06-30 16:29:51 +08:00
joyqi
d7a48ce086 update hyperdown 2021-06-25 18:28:17 +08:00
joyqi
ca1dcbf8da Add smooth preview scroll. 2021-06-25 17:42:32 +08:00
joyqi
98bf0a3b6c update hyperdown 2021-06-22 17:29:01 +08:00
joyqi
70068ed5a1 fix hyperdown 2021-06-22 12:15:00 +08:00
joyqi
db6825a33d fix typo error 2021-06-18 17:26:43 +08:00
joyqi
f6d0627a77 fix 1021 2021-06-18 17:25:56 +08:00
joyqi
50c23c44c5 update hyperdown 2021-06-18 16:52:59 +08:00
joyqi
ac74c6e0cb fix #1104 2021-06-11 14:05:35 +08:00
joyqi
4861a40b9e fix #1100 2021-06-08 11:47:03 +08:00
joyqi
0e49d186f5 fix #1096
Remove `include_path` setting.
2021-05-21 16:40:48 +08:00
joyqi
13ac6f1c70 Optimize table layout.
Close #1091
2021-05-21 15:29:03 +08:00
joyqi
6164d92173 Update hyperdown 2021-05-21 11:52:13 +08:00
joyqi
2f6a0c6f36 Merge pull request #1097 from typecho/dev
Optimize admin UI on mobile platform
2021-05-21 11:46:25 +08:00
joyqi
b2f1f46528 Merge branch 'master' into dev 2021-05-21 11:32:51 +08:00
joyqi
54af368084 Add more media file types. 2021-05-21 11:30:28 +08:00
joyqi
0dbc14da02 fix workflows 2021-05-20 14:46:16 +08:00
joyqi
60fdcae8e5 fix #1077 2021-05-20 14:02:15 +08:00
joyqi
27ebdf09f0 fix #1088 2021-04-14 14:23:05 +08:00
joyqi
6558fd5e03 minify js 2021-04-03 23:30:44 +08:00
joyqi
5afcfbf3df update hyperdown 2021-04-03 22:59:17 +08:00
joyqi
b80bce520c fix #1083 2021-04-03 22:54:23 +08:00
joyqi
cc078d6f6a Merge pull request #1083 from yongirl320/trackback-bug-fix
fix get trackback param bug
2021-04-03 21:09:18 +08:00
yongirl
a85c242e09 scheme check bug 2021-04-02 14:06:47 +08:00
yongirl
714e8788e8 fix get trackback param bug 2021-04-02 13:52:26 +08:00
joyqi
bd4ffc5e1d Improve mobile UI 2021-03-21 01:15:19 +08:00
joyqi
95ef1d562e fix touch event 2021-03-20 20:30:42 +08:00
joyqi
3fdaed97e3 Improve mobile UI. 2021-03-20 02:13:55 +08:00
joyqi
f775a3e490 Fix dashboard menu display on mobile platform(still working on it). 2021-03-19 18:34:04 +08:00
joyqi
eba20a69f0 fix #1074
fix #966
2021-03-19 01:33:08 +08:00
joyqi
452be71d87 Choose utf8mb4 and InnoDB as default mysql settings. 2021-03-19 00:12:26 +08:00
joyqi
99df2bae64 update hyperdown 2021-03-18 14:23:19 +08:00
joyqi
834e4722a0 Merge branch 'master' of github.com:typecho/typecho 2020-12-18 16:15:20 +08:00
joyqi
3b7d2dc319 fix #1049 2020-12-18 16:15:02 +08:00
joyqi
e563687451 Merge pull request #1045 from typecho/dependabot/npm_and_yarn/tools/ini-1.3.8
Bump ini from 1.3.5 to 1.3.8 in /tools
2020-12-17 00:46:31 +08:00
dependabot[bot]
ab6284abf7 Bump ini from 1.3.5 to 1.3.8 in /tools
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-12 17:38:37 +00:00
joyqi
63b71df244 Merge pull request #1039 from rakiy/master
php8正式移除了类名相同的构造方法的支持
2020-12-10 18:30:42 +08:00
alex.xu
f8d39927ce php8正式移除了类名相同的构造方法的支持 2020-12-10 15:02:16 +08:00
joyqi
f9dfb1bb85 fix #1034 2020-11-30 12:07:16 +08:00
joyqi
1cc3066569 fix #1030 2020-11-24 16:06:06 +08:00
joyqi
cee119eb4d upgrade HyperDown 2020-11-19 17:03:00 +08:00
joyqi
269832aa85 fix 2020-10-09 10:46:53 +08:00
joyqi
74c8143825 fix #1008 2020-10-03 21:20:27 +08:00
joyqi
bba332531b Redesign the pot file maker 2020-08-19 12:57:18 +08:00
joyqi
06876225c1 Merge pull request #990 from typecho/dependabot/npm_and_yarn/tools/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19 in /tools
2020-07-21 14:44:08 +08:00
dependabot[bot]
a26e2d5a33 Bump lodash from 4.17.15 to 4.17.19 in /tools
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-20 17:33:29 +00:00
joyqi
cacb854d42 Merge pull request #979 from idawnlight/master
fix: array and string offset access syntax with curly braces is no longer supported on PHP 8
2020-06-28 14:42:28 +08:00
idawnlight
a387458fc6 ci: add tests on php 8 & drop travis ci 2020-06-28 01:31:26 +08:00
idawnlight
b8f8c4c489 fix: array offset access syntax with curly braces is no longer supported 2020-06-28 01:21:46 +08:00
fen
d8fe9e0463 修复失效的 cdn 链接 2020-06-17 12:19:43 +08:00
joyqi
0b68fa8b14 fix #968 2020-06-11 18:08:32 +08:00
joyqi
65455bc67e fix typo error 2020-05-17 13:55:22 +08:00
joyqi
a4bcd37dae fix upload panel 2020-05-15 15:18:39 +08:00
joyqi
31072a0726 fix icons retina display 2020-05-15 15:08:36 +08:00
joyqi
75227b3bac fix editor button generator 2020-05-15 12:19:26 +08:00
joyqi
38f959890d replace compass with node-sass.
create new build tools.
2020-05-14 14:30:19 +08:00
joyqi
77ef00e1a0 Merge pull request #955 from atomlong/master
Support Windows Live Writer and Open Live Writer.
2020-05-14 11:23:20 +08:00
Atom Long
09a81d394c Merge branch 'master' of https://github.com/typecho/typecho 2020-05-12 17:32:38 +08:00
Atom Long
78e2dfbde8 fixed code indent, TAB --> 4 spaces 2020-05-12 17:29:41 +08:00
joyqi
3413dfd7ce fix #954 2020-05-12 16:21:59 +08:00
joyqi
371e6c9884 Merge pull request #957 from starskim/master
添加GitHub Actions Ci
2020-05-12 16:19:30 +08:00
joyqi
6398551ac3 fix #952 2020-05-12 16:08:43 +08:00
Stars_Kim
beeeab869d 添加GitHub Actions Ci 2020-05-09 16:05:33 +08:00
Atom Long
408cb56ce1 Fix #334: Support uploading pictures using Windows Live Writer or Open Live Writer. 2020-05-09 00:20:50 +08:00
Atom Long
029579be4d IXR_Error is a class, not a function. 2020-05-09 00:08:06 +08:00
joyqi
5ba2f03206 fix #945 2020-04-08 00:56:47 +08:00
joyqi
691b43bc48 fix #941 2020-04-01 17:17:31 +08:00
joyqi
3cc75893da close #940
fix #936
2020-04-01 17:10:44 +08:00
joyqi
3afd22c12c Merge branch 'master' of https://github.com/typecho/typecho 2020-03-10 10:48:09 +08:00
joyqi
3bba7cd9dd fix #926
close #928
2020-03-10 10:47:40 +08:00
joyqi
0020814e18 Merge pull request #853 from Seevil/patch-2
修复最近回复链接
2020-01-17 10:50:55 +08:00
joyqi
8d2aa236b1 fix 2019-12-19 22:15:15 +08:00
joyqi
d695ce3ce5 Merge pull request #871 from AlanDecode/master
修复通过 metaWeblog 接口新建草稿时返回 cid 错误的问题
2019-12-18 11:47:49 +08:00
joyqi
ac1527ce43 Merge pull request #901 from jeaxnew/patch-1
Update Request.php
2019-12-18 11:41:22 +08:00
jeaxnew
9948a62557 Update Request.php
fix #567
2019-11-13 19:04:56 +08:00
joyqi
75237e6a44 fix #896 2019-10-31 16:47:33 +08:00
joyqi
c17bdaf606 Merge pull request #882 from kraity/master
修复 XmlRpc 接口的几个错误问题
2019-09-03 14:10:53 +08:00
joyqi
147f7ede98 fix #881
Add 'setInputsAttribute' method for all form element classes.
2019-09-03 13:44:16 +08:00
权那他
5abd915678 解决无法判断该独立页面是否有草稿 2019-08-23 13:20:52 +08:00
权那他
64a66be475 解决无法编辑独立页面 2019-08-23 13:19:51 +08:00
权那他
71c72c7926 修正XMLRPC不能获取文章是否有草稿状态
修正XMLRPC不能获取文章是否有草稿状态
1608行
$this->typechoToWordpressStatus($posts->status, 'post')
改为
$this->typechoToWordpressStatus(($posts->hasSaved || 'post_draft' == $posts->type) ? 'draft' : $posts->status, 'post')
2019-08-18 10:16:54 +08:00
权那他
6d27a24fb8 修正XMLRPC只能发表发布状态的问题,修正后可以发布私密、草稿、等等状态的文章
修正XMLRPC只能发表发布状态的问题,修正后可以发布私密、草稿、等等状态的文章
在1442行
$status = $this->wordpressToTypechoStatus($content["{$type}_status"], $type);
后面增加一行判断
$input['visibility'] = isset($content["visibility"]) ? $content["visibility"] : $status;
2019-08-18 10:14:26 +08:00
权那他
2e2835ce6b 修复用XMLRPC获取评论时无法得到垃圾评论和待审核评论
修复用XMLRPC获取评论时无法得到垃圾评论和待审核评论
1056行
$input['status'] = 'hold' == $input['status'] ? $input['status'] : $this->wordpressToTypechoStatus($struct['status']); 
改为
$input['status'] = $this->wordpressToTypechoStatus($struct['status'], 'comment');
2019-08-18 10:11:17 +08:00
AlanDecode
664d8bcb23 修复通过 metaWeblog 接口新建草稿时返回 cid 错误的问题 2019-06-11 10:06:44 +08:00
Intern
4df129b01c 修复最近回复链接
用户链接把评论链接覆盖掉了导致并不能点击前往回复的链接地址
2019-04-12 22:52:17 +08:00
joyqi
32c2f8217d fix #845 2019-03-16 14:50:13 +08:00
那他
91d83d40b1 BUG 2019-02-11 17:03:53 +08:00
那他
0cf11bb933 Update Dockerfile 2019-02-11 16:55:15 +08:00
那他
4155491719 Update Dockerfile 2019-02-11 16:31:08 +08:00
joyqi
8045a0d403 fix #821 2019-01-10 00:24:38 +08:00
joyqi
57a5857c1f Merge pull request #820 from xyuanmu/patch-2
fix Undefined variable: options in Fake.php
2018-12-26 11:06:46 +08:00
xyuanmu
632ac977ee Update Fake.php
测试发现,这个值是不需要的
2018-12-22 12:05:02 +08:00
xyuanmu
247aa9e043 fix Undefined variable: options in Fake.php 2018-12-14 23:14:57 +08:00
joyqi
9f8491076f add missing options 2018-11-26 14:20:08 +08:00
joyqi
f4a34e0d7b fix 2018-11-26 14:15:25 +08:00
joyqi
b6626e42d8 fix error 2018-11-26 13:28:19 +08:00
joyqi
26b70e2af8 Add function: mark status of multi posts. 2018-11-26 11:38:45 +08:00
joyqi
586492e1b8 Merge pull request #801 from jrotty/patch-1
增加标签统计
2018-11-21 13:32:00 +08:00
jrotty
430649df81 增加标签统计 2018-11-10 14:21:07 +08:00
joyqi
3050aa98ab Merge pull request #798 from renothing/ssl-proxy-to-http
fix error when use different protocol between reverse proxy and backend.
2018-10-30 10:31:17 +08:00
renothing
1e7e7e7997 fix error when use different protocol between reverse proxy and backend. 2018-10-28 05:41:02 +08:00
joyqi
235888cc3e fix typo 2018-10-23 16:39:15 +08:00
joyqi
0b1096c588 Now you can paste an image from clicpboard into the editor directly. 2018-10-23 16:29:48 +08:00
joyqi
ad10000aca Merge pull request #782 from Seevil/patch-1
解决插件注入右上角导航会有两个 | | 出现
2018-10-23 14:37:05 +08:00
joyqi
a6fe58e5b2 fix #785 2018-10-23 14:33:33 +08:00
joyqi
e492f9df4d Merge pull request #785 from hongweipeng/noopener
设置noopener防止钓鱼攻击
2018-10-23 14:25:31 +08:00
hongweipeng
350b2edb2b 设置noopener防止钓鱼攻击 2018-09-29 13:40:22 +08:00
joyqi
b70d240d3a fix #755 2018-09-26 11:52:56 +08:00
joyqi
6fbb65487c Remove auto complete for some input elements. 2018-09-26 11:11:44 +08:00
joyqi
b497004516 fix #753 2018-09-26 11:07:07 +08:00
Intern
a920bffd77 解决插件注入右上角导航会有两个 | | 出现
解决插件注入右上角导航会有两个| | 出现,如:插件名| |用户名|登出|网站 此种现象出现,原因为换行空格导致的。
2018-09-19 22:39:35 +08:00
joyqi
df7aeda761 Merge pull request #780 from bestony/add-gmail-support
fix: Support plus in email address
2018-09-07 10:55:49 +08:00
Bestony
2a8b11f48b fix: Support plus in email address
fix: add support in email address (just like example+typecho@gmail.com)
2018-09-06 10:54:42 +08:00
joyqi
c2a71c2f19 fix #769 2018-08-27 11:53:39 +08:00
joyqi
94ddb69311 Merge branch 'master' of github.com:typecho/typecho 2018-08-19 14:24:06 +08:00
joyqi
27dce21870 update hyperdown 2018-08-19 14:23:52 +08:00
joyqi
e942452197 Merge pull request #772 from h404bi/patch-1
chore: fix wrong slug prompt
2018-08-19 13:47:28 +08:00
Chawye Hsu
d93af07d31 chore: fix wrong slug prompt 2018-08-18 17:27:29 +08:00
joyqi
3303b435ad add reset 2018-07-30 12:05:28 +08:00
joyqi
03f237b32f Merge pull request #767 from idawnlight/master
修正错误的数据堆栈
2018-07-30 11:55:53 +08:00
dawnlight
cbc08861f4 修正错误的数据堆栈
减少一次 `count` 运算
2018-07-28 13:55:00 +08:00
joyqi
df5f747975 Merge pull request #766 from leenzhu/fix-752
fix #752
2018-07-28 12:35:06 +08:00
joyqi
02929ea4f5 update hyperdown 2018-07-25 10:58:53 +08:00
joyqi
ee409f1ee1 Merge branch 'master' of github.com:typecho/typecho 2018-07-25 10:56:39 +08:00
joyqi
1d56948c4d fix img load event 2018-07-25 10:56:09 +08:00
dawnlight
8d4c8698de 修正错误的数据堆栈 2018-07-23 12:38:23 +08:00
dawnlight
e72e723c1e 修正错误的数据堆栈
在没有评论且开启评论分页的情况下,$this->row 会被错误地赋值为 false,在之后通过魔术方法 __get 获取内部变量时会抛出警告
Warning: array_key_exists() expects parameter 2 to be array, boolean given
2018-07-23 10:40:44 +08:00
leenzhu
68db3cd2ab fix #752 2018-07-21 20:27:52 +08:00
joyqi
a2d21f1042 Merge pull request #757 from jrotty/master
修正编辑器预览界面代码不自动换行问题
2018-05-31 16:18:45 +08:00
jrotty
c0965ad200 修正编辑器预览界面代码不自动换行问题
编辑器预览界面,代码太长而没有换行会戳出屏幕外,故修复下,让其自动换行
2018-05-27 10:26:12 +08:00
joyqi
6530443e41 Merge pull request #735 from mrasong/master
bug fixed: Typecho_Plugin::exists()
2018-03-25 00:32:37 +08:00
mrasong
93a4bbdc20 bug fixed: Typecho_Plugin::exists() 2018-03-24 01:37:07 +08:00
joyqi
92a40c87a5 fix #724 2018-03-23 12:39:25 +08:00
joyqi
d745863e54 fix hyperdown
remove unnecessary js
2018-03-23 12:06:44 +08:00
joyqi
717a3b1afa Merge pull request #725 from mierhuo/master
fix logical mistake of HyperDown->optimizeBlocks
2018-03-23 11:42:11 +08:00
joyqi
dd2876f484 Merge pull request #733 from allen05ren/master
修复一处输入错误
2018-03-23 11:30:20 +08:00
allen05ren
10593d8172 fix typo. 2018-03-21 23:11:07 +08:00
joyqi
7900c1b740 fix backup file version 2018-03-15 13:23:35 +08:00
joyqi
13c1986f02 Add error correcting mode for backup recovery 2018-03-14 22:00:49 +08:00
joyqi
76c7eb757b fix i18n function 2018-03-08 12:11:49 +08:00
joyqi
09d9c3a944 Merge pull request #714 from mierhuo/master
delete some redundant code in file install.php(config.inc.php as well)
2018-03-08 12:09:37 +08:00
joyqi
1e0b2bca4b fix table style 2018-03-08 12:01:01 +08:00
joyqi
9e78add245 Merge pull request #726 from mierhuo/master
update normalize.css for admin panel and default theme
2018-03-08 11:36:45 +08:00
Huspy
143eeaa7b5 update normalize.css for admin panel and default theme 2018-03-08 00:01:58 +08:00
joyqi
a622aa41d7 Merge pull request #720 from insomnux/i18n
added gettext in a few strings in backup.php and Discussion.php
2018-03-07 10:54:54 +08:00
joyqi
307f0e0823 Merge pull request #723 from jrotty/patch-1
删除多余的冒号
2018-03-07 10:53:49 +08:00
Huspy
04ff4b4c9c fix logical mistake of HyperDown->optimizeBlocks 2018-03-06 15:58:08 +08:00
jrotty
b04996d917 删除多余的冒号 2018-03-05 15:47:57 +08:00
joyqi
eae806390b fix empty column 2018-02-26 12:52:06 +08:00
insomnux
96570e93b9 added gettext in a few strings in backup.php and Discussion.php 2018-02-23 13:21:57 +02:00
Huspy
4ce7490b3b delete some redundant code in file install.php(config.inc.php as well) 2018-02-04 20:09:14 +08:00
joyqi
3848176990 fix Chinese symobl 2018-02-03 12:31:30 +08:00
joyqi
02dd3f997f fix #710 2018-01-29 18:40:43 +08:00
joyqi
82212edba0 fix #1343 2018-01-22 11:42:59 +08:00
joyqi
2ff40c4869 fix textarea focus 2017-12-14 18:56:07 +08:00
joyqi
8c5f967f86 update version 2017-12-14 14:07:54 +08:00
joyqi
c3abcccf35 remove unused variables 2017-12-14 14:07:11 +08:00
joyqi
42495b36a3 fix plugin version check 2017-12-14 11:37:15 +08:00
joyqi
2e9f64a7f7 fix #689 2017-12-14 11:27:42 +08:00
joyqi
72ebc723b7 双向滚动绑定 2017-12-14 02:27:51 +08:00
joyqi
b59785563f fix line 2017-12-13 18:17:43 +08:00
joyqi
88b1aa465c 编辑器同步跟随功能 2017-12-13 16:55:08 +08:00
joyqi
1e82962b37 testing auto scroll 2017-12-12 19:07:12 +08:00
joyqi
f2731b7263 fix markdown list parser
fix #688
fix #678
2017-12-11 11:49:25 +08:00
joyqi
f3dab3996d fix #682 2017-12-08 18:38:19 +08:00
joyqi
dd79918d2e fix #676 2017-11-23 15:01:28 +08:00
joyqi
c57f34b3eb detect editor change event 2017-11-20 12:51:15 +08:00
joyqi
19450df26b Protect iframe with sandbox 2017-11-20 10:35:10 +08:00
joyqi
1a2dd1a812 fix #673 2017-11-20 03:05:10 +08:00
joyqi
1faf5b2199 improve ajax performance 2017-11-20 02:50:48 +08:00
joyqi
d70998ac81 finish preview 2017-11-19 21:58:11 +08:00
joyqi
ab180aa385 add preview function 2017-11-19 18:51:27 +08:00
joyqi
b8788c9e7e fix #671 2017-11-17 10:32:07 +08:00
joyqi
452fac4099 fix service url 2017-11-15 18:35:47 +08:00
joyqi
97390a2af5 update plupload 2017-11-15 17:51:29 +08:00
joyqi
77df79871b fix 2017-11-15 14:52:01 +08:00
joyqi
f180e8452d add async service for plugin 2017-11-15 14:25:02 +08:00
joyqi
5f3620e058 fix plugin helper 2017-11-15 11:43:32 +08:00
joyqi
abcecb124d close #662 2017-11-12 16:21:41 +08:00
joyqi
4a5f1aece1 fix #652
fix #612
2017-11-09 12:44:36 +08:00
joyqi
10a40c4683 fix #658
fix #659
2017-11-09 10:05:03 +08:00
joyqi
dabbdc8af9 ref #653
make hyperdown better
2017-11-08 13:17:01 +08:00
joyqi
72c236f651 fix #653
fix #655
2017-11-07 23:13:38 +08:00
joyqi
36742a6fdb fix #650
ref #580
2017-11-04 12:12:30 +08:00
joyqi
fee8bcc63c fix #651 2017-11-03 10:19:47 +08:00
joyqi
cf002bb0c0 fix #643 2017-11-03 00:29:58 +08:00
joyqi
425add976d fix #649 2017-11-02 23:20:47 +08:00
joyqi
5da128b0c7 Merge branch 'master' of https://github.com/typecho/typecho 2017-11-01 23:06:57 +08:00
joyqi
20732c1e89 fix #648 2017-11-01 23:06:29 +08:00
joyqi
5c2276c73f ref #644 2017-11-01 19:07:30 +08:00
joyqi
f2dc80592e fix #644
ref #642
2017-11-01 18:16:59 +08:00
joyqi
79dfede306 Merge pull request #646 from bighamx/patch-1
Update install.php
2017-11-01 18:14:20 +08:00
SpanishBigHam
827a085c5e Update install.php
cache html output until all headers seted
2017-11-01 14:54:41 +08:00
joyqi
bf4408d6da remove ACE support 2017-11-01 00:05:57 +08:00
joyqi
a48f7ea48b fix #642 2017-10-31 23:56:20 +08:00
joyqi
b68c45ca93 fix #640 2017-10-31 23:52:03 +08:00
joyqi
adfbc6ca28 fix #641 2017-10-30 20:57:04 +08:00
joyqi
b3dbef1377 fix #623 2017-10-30 13:16:15 +08:00
joyqi
9e1b61e0f0 fix #637 2017-10-30 12:11:13 +08:00
joyqi
c056f6c895 fix #636 2017-10-30 11:50:35 +08:00
joyqi
ac1c62a07d new release 2017-10-30 02:57:57 +08:00
joyqi
93bcd46d55 fix #635
fix #634
fix #633
2017-10-30 02:19:53 +08:00
joyqi
a214977c83 release new version 2017-10-29 17:37:18 +08:00
joyqi
01d3badc9b Add new constants for dynamic site url
fix #630
2017-10-29 16:11:37 +08:00
joyqi
9884a2fc76 fix #628 2017-10-29 15:45:47 +08:00
joyqi
7a2b374526 Merge branch 'master' of https://github.com/typecho/typecho 2017-10-29 13:07:48 +08:00
joyqi
92f81b3004 add client timezone 2017-10-29 13:07:15 +08:00
joyqi
95e62ce30a Add a security check step before upgrade 2017-10-28 15:03:59 +08:00
joyqi
3517eff4de fix #626 2017-10-27 19:40:37 +08:00
joyqi
8191c8fcea Merge branch 'master' of github.com:typecho/typecho 2017-10-27 16:42:29 +08:00
joyqi
ed0af49767 Add a switch for xmlrpc in general control panel. 2017-10-27 16:42:13 +08:00
joyqi
adafe05caf Merge branch 'master' of https://github.com/typecho/typecho 2017-10-27 00:43:32 +08:00
joyqi
da1e1b8d3b fix #624 2017-10-27 00:43:08 +08:00
joyqi
ef4ee2f9b0 fix unicode for hyperdown 2017-10-26 12:24:39 +08:00
joyqi
f955076905 fix upgrade 2017-10-26 11:12:26 +08:00
joyqi
fefedb3866 fix make tools 2017-10-26 10:44:27 +08:00
joyqi
7d229b55ee fix #616 2017-10-24 17:03:07 +08:00
joyqi
e277141c97 fix #619
使用更好的方式保护安装文件,不再依赖session
2017-10-24 16:59:31 +08:00
joyqi
242fc1a4cb fix some minor bugs 2017-10-13 11:03:38 +08:00
joyqi
eeedef972a fix pingback's security issue
ref: https://joychou.org/web/typecho-ssrf-analysis-and-exploit.html
2017-10-13 01:01:11 +08:00
joyqi
0e7b399ba8 Merge branch 'master' of github.com:typecho/typecho 2017-09-28 13:06:02 +08:00
joyqi
eaa7d28823 fix #610 2017-09-28 13:05:51 +08:00
joyqi
b97289f7eb Merge pull request #607 from jrotty/master
主题缩略图使用screenshot命名的图片
2017-09-21 17:39:06 +08:00
jrotty
6005d80b20 主题缩略图使用screenshot命名的图片
修复主题根目录存在screenshot.png和其他图片时,主题展示图抓取其他图片的问题
2017-09-19 10:42:51 +08:00
joyqi
55c676d6a5 fix autoload 2017-09-15 01:44:43 +08:00
joyqi
b1c0185d85 Merge branch 'master' of github.com:typecho/typecho 2017-09-08 14:49:46 +08:00
joyqi
ed8a847ae6 add new helper method
add new plugin callback method
2017-09-08 14:49:29 +08:00
joyqi
f3a28f38e2 add method to get query params 2017-08-22 01:29:44 +08:00
joyqi
ae684c3a82 ref #459 2017-08-21 17:07:32 +08:00
joyqi
3c171785d2 remove session requirement 2017-08-21 12:46:49 +08:00
joyqi
949b487445 fix query error 2017-08-21 11:49:36 +08:00
joyqi
d953e32003 add delay binding
fix #601
2017-08-21 11:43:10 +08:00
joyqi
c3c6723d7b fix typo error 2017-08-19 18:01:19 +08:00
joyqi
bcfbc07bac fix #599 2017-08-18 16:14:14 +08:00
joyqi
0ba45f1006 fix antispam method 2017-08-18 14:20:20 +08:00
joyqi
13fc1b7169 add validate meta info for the backup file 2017-08-18 11:09:46 +08:00
joyqi
ac11ff4cc9 add mathjax support for markdown parser 2017-08-17 15:18:03 +08:00
joyqi
a5c3e5aca7 finish backup description 2017-08-17 13:00:26 +08:00
joyqi
f2ba3071fd fix null value 2017-08-17 12:53:07 +08:00
joyqi
c1584509e2 finish backup recovery 2017-08-17 12:28:29 +08:00
joyqi
aa2eac4dcc 导入逻辑基本完成 2017-08-16 23:15:47 +08:00
joyqi
3d8fbc8a61 add backup panel 2017-08-16 18:09:39 +08:00
joyqi
43995a346d Merge branch 'master' of github.com:typecho/typecho 2017-08-15 11:35:54 +08:00
joyqi
4ac142ce9e add new plugin hook 2017-08-15 11:35:38 +08:00
joyqi
2849cc089d Merge pull request #598 from l2dy/master
Fix X-UA-Compatible
2017-08-14 15:32:36 +08:00
Zero King
2627638192 Update X-UA-Compatible 2017-08-12 00:43:56 +00:00
joyqi
43653242ed Merge branch 'master' of github.com:typecho/typecho 2017-08-10 10:28:06 +08:00
joyqi
d486a30a6d fix #596 2017-08-10 10:27:52 +08:00
joyqi
80b5323fe2 Merge pull request #592 from l2dy/master
url是BlogPosting的属性
2017-08-09 14:11:29 +08:00
joyqi
41751a3625 fix #597 2017-08-09 14:10:41 +08:00
joyqi
eb68b52800 新增 $this->directory() 方法,用来方便地输出多级分类
ref #597
2017-08-09 12:52:31 +08:00
joyqi
24cc1f5a5e fix #595
感谢 @eslizn 找到的问题,我用了更优雅的方式解决
2017-08-04 13:22:17 +08:00
joyqi
9bcfc8141a add table style for preview 2017-08-02 15:25:33 +08:00
joyqi
776e45473c 修正contents表安装时的数据类型为longtext
修复HyperDown的一个解析错误
2017-08-02 11:11:46 +08:00
Zero King
62d0013d41 url是BlogPosting的属性 2017-08-01 10:08:38 +00:00
joyqi
3bf5d07fa2 remove php 5.3 from travis-ci list 2017-07-31 11:44:32 +08:00
joyqi
597ff5ec11 Merge pull request #589 from l2dy/master
for属性只对应id,给input补上id属性
2017-07-31 01:44:37 +08:00
Zero King
a1b1915dfb label的for属性只对应id,给input补上id属性 2017-07-29 22:39:39 +00:00
joyqi
56dfd2f093 增加一个官方的 Telegram 消息发布渠道
https://t.me/typechodev
方便我适时发布相关消息
2017-07-28 17:30:37 +08:00
joyqi
8043d96d03 fix #586 2017-07-27 11:05:02 +08:00
joyqi
f88cd44d52 fix #577
fix #581
2017-07-24 16:35:54 +08:00
joyqi
98ed395962 remove hhvm 2017-05-10 11:57:55 +08:00
joyqi
966ecf74f1 fix column 2017-05-10 11:55:41 +08:00
joyqi
5cb34a6e82 fix #559 2017-05-10 11:51:55 +08:00
joyqi
16a74d5cc9 add cli mode 2017-05-09 17:38:09 +08:00
joyqi
b3ce12c575 fix xmlrpc post 2017-04-25 15:43:46 +08:00
joyqi
a159292173 fix typo 2017-04-25 13:57:05 +08:00
joyqi
93a3229c6d fix user options 2017-04-25 13:54:10 +08:00
joyqi
9122d2ab49 支持在xmlrpc接口中使用原生的markdown语法 2017-04-25 12:44:08 +08:00
joyqi
7cdc244d95 修正xmlrpc 2017-04-24 15:55:47 +08:00
joyqi
1366f44ada 增加兼容性 2017-04-17 19:04:19 +08:00
joyqi
47e10dcf53 Merge pull request #554 from JimmehCai/master
Fix "insertTo is not a function"
2017-04-06 11:08:10 +08:00
Jimmy Cai
9b03f1b5a2 Fix "insertTo is not a function"
insertTo > insertAfter
2017-04-04 14:37:11 +02:00
joyqi
909145058f enable super html mode 2017-03-30 17:00:30 +08:00
joyqi
b008bfbc96 增加超级html模式,可以输入由 !!! 三个感叹号包裹的任意html文本 2017-03-30 16:56:08 +08:00
joyqi
2f2c2d5910 fix #552 2017-03-30 15:09:28 +08:00
joyqi
8ac2087abc Merge pull request #544 from ldsink/master
fix: Mysqli quoteColumn 函数参数调用错误
2017-02-27 01:30:33 +08:00
zhoucheng
694a22a295 fix: Mysqli quoteColumn 函数参数调用错误 2017-02-25 22:30:37 +08:00
joyqi
44497599f6 add ci for php 7 2017-02-24 15:36:37 +08:00
joyqi
14f75b001c Update Makefile 2017-02-24 15:33:54 +08:00
fen
cca12d16e3 调整拼写及顺序 2017-02-21 13:47:05 +08:00
fen
3a438d1084 添加 github issue 模板 2017-02-21 13:43:00 +08:00
joyqi
2fe30b0837 fix typo 2017-02-19 23:03:41 +08:00
joyqi
e241ff09b0 fix #534 2017-02-19 01:17:41 +08:00
joyqi
e39183915b Merge branch 'master' of https://github.com/typecho/typecho 2017-02-19 00:47:10 +08:00
joyqi
43f3e686c6 fix #532 2017-02-19 00:46:50 +08:00
joyqi
3b9ae9c498 add timezone 2017-02-09 17:16:38 +08:00
joyqi
f2ebf4b10a add some useful html tag to markdown whitelist 2017-01-25 12:12:25 +08:00
joyqi
b9dc6a61ad add ignore tag 2017-01-25 11:51:28 +08:00
joyqi
03f928d4d9 fix #527 2017-01-25 11:47:13 +08:00
joyqi
8ac87dd5b2 Merge branch 'master' of github.com:typecho/typecho 2017-01-25 11:40:56 +08:00
joyqi
c5e1e3c6df fix #529 2017-01-25 11:40:48 +08:00
joyqi
1372cc4242 Merge pull request #531 from kokororin/master
修复后台数字序号样式自动换行
2017-01-25 11:37:50 +08:00
Kokororin
6bcae91008 修复后台数字序号样式自动换行 2017-01-24 18:47:45 +08:00
joyqi
134a300861 Merge pull request #525 from ty666/master
修复聚合调用时的判断问题
2017-01-06 11:04:27 +08:00
taoyu
8150e1a6a0 修复聚合调用时的判断问题 2017-01-05 23:35:11 +08:00
joyqi
42eb5c4744 Merge branch 'master' of github.com:typecho/typecho 2017-01-04 10:24:48 +08:00
joyqi
7653c5e0ff fix #522 2017-01-04 10:24:38 +08:00
joyqi
325f0e3486 fix #524 2017-01-02 19:09:00 +08:00
joyqi
cca53464df fix port number 2016-12-23 00:44:10 +08:00
joyqi
f28e909987 fix dockerfile 2016-12-23 00:43:56 +08:00
joyqi
e25022ecc1 fix install issue
add Dockerfile
2016-12-22 18:54:28 +08:00
fen
820828757a Merge branch 'master' of github.com:typecho/typecho 2016-12-20 12:52:04 +08:00
fen
a40767a01d 将默认模板的时间格式与后台设置关联 2016-12-20 12:51:47 +08:00
joyqi
12c4b8fe98 修正解析顺序 2016-12-14 10:56:38 +08:00
joyqi
627e5cf54e minor bugs 2016-11-30 10:58:30 +08:00
joyqi
cc8449b67e * add Hyperdown.js
* add Mysqli
2016-11-30 10:50:51 +08:00
joyqi
280bc71c0c Merge pull request #459 from skys215/master
Added support for MySQLi
2016-11-30 10:34:38 +08:00
joyqi
d2631fde2b Merge pull request #512 from Meekdai/master
解决BAE新版本不支持HTTP_BAE_LOGID变量获取导致BAE无法安装的问题
2016-11-30 10:30:30 +08:00
Meekdai
c968abae08 解决BAE新版本不支持HTTP_BAE_LOGID变量获取导致BAE无法安装的问题 2016-10-26 00:20:29 +08:00
fen
b675161c79 调整自定义 logo 样式 2016-07-17 18:24:28 +08:00
fen
0a04ab9924 调整标题字体 2016-07-17 18:06:43 +08:00
fen
cd65eaf6cb 调整后台可用性及并修复搜索 bug 2016-07-17 18:04:49 +08:00
fen
89293e80aa Merge branch 'master' of github.com:typecho/typecho 2016-07-16 13:07:57 +08:00
fen
437ba872c1 避免第三方插件模板开发时影响提交
移除已完成的 todo 文件
2016-07-16 13:07:38 +08:00
Fen
8d04c20ed5 fixed issue #474 2016-07-16 12:11:21 +08:00
Fen
a2e519beeb Merge pull request #452 from xiabeifeng/patch-6
将cancle改成cancel
2016-07-09 10:39:47 -05:00
skys215
37ab647895 Mysql->Mysqli 2016-03-20 21:00:30 +08:00
skys215
0464ad729c Added support for MySQLi 2016-03-20 12:50:28 +00:00
Fen
7195666f09 Merge pull request #450 from xiabeifeng/patch-2
我的IDE在selected=true这个地方提示我"没有定义的属性值"
2016-03-10 09:59:13 +08:00
xiabeifeng
1ab9e68f0f 将cancle改成cancel
cancel:取消
2016-03-09 20:25:48 +08:00
xiabeifeng
8553a8b6b9 我的IDE在selected=true这个地方显示没有定义的属性值
网上查了查w3c,发现标准的用例使用的是selected="selected",而在js代码中使用selected=true来更改状态,具体可见下列网址:
1.在html标签中使用selected="selected"
    http://www.w3school.com.cn/tags/att_option_selected.asp
2.在js中使用selected=true
    http://www.w3school.com.cn/jsref/prop_option_selected.asp
2016-03-09 16:14:37 +08:00
joyqi
0d371d4816 fix the display method of plugin's personal options 2016-02-18 14:47:13 +08:00
joyqi
0082816f53 Merge pull request #439 from kookxiang/personal-config-fix
修正个人设置中插件接口错位的问题
2016-02-18 14:41:38 +08:00
kookxiang
26745edeb5 Fix personal config page style 2016-02-11 23:07:33 +08:00
祁宁
394b93bbd2 fix more split 2016-02-08 15:59:24 +08:00
joyqi
2903f6a191 fix #435 2016-01-28 15:31:11 +08:00
joyqi
59bc86ff46 upgrades plupload 2016-01-26 18:32:08 +08:00
joyqi
ed974cd9fe fix #316
fix #390
fix #430

add constants __TYPECHO_URL_PREFIX__ to custom global url prefix
2016-01-26 17:50:26 +08:00
joyqi
87a0479324 Merge pull request #387 from helone/patch-1
删除 Chrome Frame 的支持
2016-01-26 15:28:45 +08:00
joyqi
93a3bc5c4c remove php 5.2 2016-01-26 15:28:02 +08:00
joyqi
30cbefc453 Merge pull request #428 from ldsink/phpdoc
update PHPDoc comments
2016-01-26 15:08:15 +08:00
joyqi
2613916d15 Merge pull request #411 from mikeyzm/master
设置搜索归档缩略名
2016-01-26 15:07:33 +08:00
joyqi
55dff6347a Merge pull request #427 from ldsink/typo
修复 iconv 函数参数传递错误
2016-01-26 14:52:36 +08:00
joyqi
86ae20bfbb Merge pull request #425 from MioMioReimu/master
bugfix: In function 'treeViewCategoriesCallback' , the item Tag is hardcode w…
2016-01-26 14:50:51 +08:00
joyqi
44141c5727 Merge pull request #393 from tridays/master
修复检测不到 $_server['SERVER_PORT'] 导致无法访问后台的问题。
2016-01-26 14:48:56 +08:00
joyqi
d6fc7f182f fix array 2016-01-26 14:43:32 +08:00
joyqi
2200d86e8a fix new line 2016-01-26 12:55:22 +08:00
joyqi
1c140a563a fix array 2016-01-26 12:04:56 +08:00
joyqi
c58a9530b1 fix #416 2016-01-25 16:58:27 +08:00
joyqi
eca450855e fix #407 2016-01-25 16:37:16 +08:00
joyqi
43087d6370 Replace the markdown parse engine with HyperDown 2016-01-25 16:21:04 +08:00
zhoucheng
d10701f743 update phpdoc in Plugin 2015-12-23 17:57:11 +08:00
zhoucheng
3955ccd85b use space instead tab to vertically align code 2015-12-23 17:29:03 +08:00
zhoucheng
50b2b9c591 add phpdoc 2015-12-23 17:26:18 +08:00
zhoucheng
32249ab897 fix iconv function param error 2015-12-23 17:14:30 +08:00
tlm
e311837418 In function 'treeViewCategoriesCallback' , the item Tag is hardcode with 'li' . It should be replaced by itemTag. 2015-12-15 14:20:33 +08:00
joyqi
35d2908934 Merge pull request #422 from ldsink/master
update PHPDoc comments
2015-12-08 23:24:27 +08:00
ldsink
925daaeb63 constructors, the @return tag MAY be omitted here, in which case @return self is implied. 2015-12-08 21:50:59 +08:00
ldsink
a498669ad8 add excption throws 2015-12-08 21:42:02 +08:00
ldsink
e3cdc44edc process Widget 2015-12-08 21:36:13 +08:00
ldsink
1d1b79b6cf update PHPDoc comments 2015-12-08 21:19:36 +08:00
joyqi
1ccd804a40 Merge pull request #412 from JShadowMan/patch-1
Update Db.php
2015-11-14 14:34:38 +08:00
joyqi
6f6cf15674 Merge pull request #405 from shuax/master
typo fix
2015-11-14 14:31:29 +08:00
JShadowMan
a98472c1bb Update Db.php
注释一个错字?
2015-11-01 13:20:42 +08:00
unknown
cc622f9ccc 设置搜索归档缩略名 2015-10-31 15:33:46 +08:00
舒俊杰
6ad6511762 typo fix 2015-10-09 21:17:47 +08:00
joyqi
fe76665687 Merge pull request #394 from lizheming/master
Json.php 中的引用错误
2015-09-29 16:16:51 +08:00
祁宁
2666641560 add php 7 check 2015-09-08 11:44:33 +08:00
lizheming
37be2afa98 fix Json.php error 2015-08-29 16:24:04 +08:00
joyqi
b257d053f6 Merge pull request #331 from dseguy/master
去掉无用的变量
2015-08-27 21:38:06 +08:00
joyqi
ce8bb8c349 Merge pull request #373 from mikeyzm/master
删除乱入的<dt>标签
2015-08-27 21:34:11 +08:00
joyqi
9e2a8214a9 Merge pull request #388 from keyingkai/master
Update header.php
2015-08-27 21:33:43 +08:00
tridays
ae7b2f49b0 修复检测不到 $_server['SERVER_PORT'] 导致无法访问后台的问题。
修改了 /var/Typecho/Request.php:222 行。
2015-08-27 21:09:24 +08:00
keyingkai
f5944fa138 Update header.php
更换到支持https的js库(cdnjs),增强了https的支持
2015-08-03 09:20:18 +08:00
helone
6ef4219b2a 删除 Chrome Frame 的支持
Google Chrome Frame已于2014年2月25日正式停止维护与更新 https://zh.wikipedia.org/wiki/Google_Chrome_Frame
2015-07-29 16:03:57 +08:00
joyqi
3d4b7babb4 Merge pull request #379 from aneasystone/master
修复两个在SAE本地环境出现的bug
2015-06-27 22:18:37 +08:00
Desmond Stonie
53a2ce64b4 __TYPECHO_MB_SUPPORTED__ needs mb_get_info and mb_regex_encoding all exist 2015-06-27 12:41:22 +08:00
Desmond Stonie
e4e0ace9a9 in some SAE environment, SAE constants like SAE_MYSQL_DB have been defined but not been initialized 2015-06-27 12:39:01 +08:00
joyqi
5f72999a44 Merge pull request #375 from byends/patch-1
Update Contents.php
2015-06-01 10:45:37 +08:00
羽飞
2aaaf9df05 Update Contents.php
修复在插件调用执行config() 方法时,不存在 text  key 时有警告提醒
2015-05-30 19:53:03 +08:00
Mike
e6e3cec3f1 删除乱入的<dt>标签 2015-05-05 10:38:20 +08:00
Damien Seguy
6e8c0f6c89 去掉无用的变量 2014-11-02 22:28:13 +01:00
422 changed files with 63950 additions and 71292 deletions

14
.editorconfig Normal file
View File

@@ -0,0 +1,14 @@
root = true
[*]
indent_style = space
indent_size = 4
[*.yml]
indent_size = 2
[*.scss]
indent_size = 2
[*.php]
insert_final_newline = true

42
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,42 @@
---
name: 上报 BUG
about: 报告问题,帮助改进项目
title: ''
labels: bug
assignees: ''
---
## 描述这个 Bug
简明扼要地描述错误是什么。
### 复现方式
复现的步骤:
1. 前往 '...'
2. 点击 '....'
3. 滚动到 '....'
4. 看到错误
### 期望的结果
简明扼要地描述你期望看到的结果。
### 截图
如果可以的话,请添加截图或视频以帮助解释你的问题。
### 平台
- 操作系统版本:
- Apache/Nginx 版本:
- 数据库版本:
- PHP 版本:
- Typecho 版本:
- 浏览器版本:

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: 论坛支持
url: https://forum.typecho.org/
about: 交流使用心得,使用模板插件,寻求帮助等等

View File

@@ -0,0 +1,23 @@
---
name: 提改进建议
about: 提出改进建议,改进项目现有功能
title: ''
labels: enhancement
assignees: ''
---
## 你的改进是否与某个问题有关?请描述
简明扼要地描述问题产生的原因。例如:当 [...] 时,我总是很困惑。
## 描述你想要的解决方案
简明扼要地描述你希望的解决方案。
## 描述你考虑过的替代方案
简明扼要地描述你考虑过的任何替代解决方案或功能。

View File

@@ -0,0 +1,23 @@
---
name: 新功能提议
about: 为项目提出一个想法或可能的新功能
title: ''
labels: feature
assignees: ''
---
## 你的想法是否与某个问题有关?请描述
简明扼要地描述问题产生的原因。例如:当 [...] 时,我总是很困惑。
## 描述你想要的解决方案
简明扼要地描述你希望的解决方案。
## 描述你考虑过的替代方案
简明扼要地描述你考虑过的任何替代解决方案或功能。

View File

@@ -0,0 +1,7 @@
Fixes #
## Proposed Changes
-
-
-

58
.github/workflows/Typecho-dev-Ci.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: Typecho Dev Test
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
php:
name: PHP ${{ matrix.php }} Tests
runs-on: ubuntu-latest
if: ${{ !contains(github.event.head_commit.message, 'skip ci') }}
strategy:
fail-fast: false
matrix:
php: ['7.4', '8.0', '8.1', '8.2']
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup PHP only
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- name: Test
run: |
find . -type f -name '*.php' -print0 | xargs -0 -n1 -P4 php -l -n | (! grep -v "No syntax errors detected" )
build:
name: Typecho Build
runs-on: ubuntu-latest
if: ${{ !contains(github.event.head_commit.message, 'skip ci') && github.event_name != 'pull_request' && github.repository == 'typecho/typecho' }}
needs:
- php
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build
run: |
mkdir build
cp -r LICENSE.txt index.php install.php admin install usr var build/
mkdir build/usr/uploads/
chmod 755 build/usr/uploads/
rm -rf build/admin/src
rm -rf build/usr/themes/classic-22/static/scss
cd build && zip -q -r typecho.zip * && mv typecho.zip ../ && cd -
- name: Upload a Build Artifact
uses: WebFreak001/deploy-nightly@v1.1.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: https://uploads.github.com/repos/typecho/typecho/releases/49532662/assets{?name,label}
release_id: 49532662
asset_path: ./typecho.zip
asset_name: typecho.zip
asset_content_type: application/zip
max_releases: 1

View File

@@ -0,0 +1,36 @@
name: Typecho Hotfix Merge
on:
pull_request:
types:
- closed
- labeled
branches:
- master
jobs:
auto-merge:
if: github.event.action == 'closed' && github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'fix/')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Merge to dev branch
uses: devmasx/merge-branch@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
from_branch: ${{ github.event.pull_request.head.ref }}
target_branch: dev
label-merge:
if: github.event.action == 'labeled' && !startsWith(github.event.pull_request.head.ref, 'fix/')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Merge to dev branch
uses: devmasx/merge-branch@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
label_name: 'merge-to-dev'
target_branch: dev

View File

@@ -0,0 +1,33 @@
name: Typecho Build Release Ci
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build
run: |
mkdir build
cp -r LICENSE.txt index.php install.php admin install usr var build/
mkdir build/usr/uploads/
chmod 755 build/usr/uploads/
rm -rf build/admin/src
rm -rf build/usr/themes/classic-22/static/scss
cd build && zip -q -r typecho.zip * && mv typecho.zip ../ && cd -
- name: Upload Release Asset
uses: shogo82148/actions-upload-release-asset@v1
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./typecho.zip
asset_name: typecho.zip
asset_content_type: application/zip
- name: Trigger language build
run: |
curl -XPOST -H "Authorization: token ${{ secrets.WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github.everest-preview+json" \
-H "Content-Type: application/json" \
https://api.github.com/repos/typecho/languages/actions/workflows/update.yml/dispatches --data '{"ref": "master"}'

13
.gitignore vendored
View File

@@ -24,5 +24,14 @@
*.sublime*
.sass-cache
config.rb
/config.inc.php
/usr/uploads/
prepros.config
config.inc.*
usr/uploads/
usr/*.db
usr/plugins/
!usr/plugins/HelloWorld
usr/themes/*
!usr/themes/default
!usr/themes/classic-22
node_modules/
tools/tmp/

0
.gitmodules vendored
View File

48
.phpstorm.meta.php Normal file
View File

@@ -0,0 +1,48 @@
<?php
namespace PHPSTORM_META {
override(\Typecho\Widget::widget(0), map([
'' => '@'
]));
exitPoint(\Typecho\Widget\Response::redirect());
exitPoint(\Typecho\Widget\Response::throwContent());
exitPoint(\Typecho\Widget\Response::throwFile());
exitPoint(\Typecho\Widget\Response::throwJson());
exitPoint(\Typecho\Widget\Response::throwXml());
exitPoint(\Typecho\Widget\Response::goBack());
override(\Widget\Options::__get(0), map([
'feedUrl' => string,
'feedRssUrl' => string,
'feedAtomUrl' => string,
'commentsFeedUrl' => string,
'commentsFeedRssUrl' => string,
'commentsFeedAtomUrl' => string,
'xmlRpcUrl' => string,
'index' => string,
'siteUrl' => string,
'routingTable' => \ArrayObject::class,
'rootUrl' => string,
'themeUrl' => string,
'pluginUrl' => string,
'adminUrl' => string,
'loginUrl' => string,
'loginAction' => string,
'registerUrl' => string,
'registerAction' => string,
'profileUrl' => string,
'logoutUrl' => string,
'serverTimezone' => int,
'contentType' => string,
'software' => string,
'version' => string,
'markdown' => int,
'allowedAttachmentTypes'=> \ArrayObject::class
]));
override(\Typecho\Widget::__get(0), map([
'sequence' => int,
'length' => int
]));
}

View File

@@ -1,12 +0,0 @@
language: php
php:
- 5.6
- 5.5
- 5.4
- 5.3
- 5.2
- hhvm
script: cd ./tools/ && set -e && make test

128
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
admin@typecho.org.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

37
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,37 @@
Contributing to Typecho
=======================
Thanks for considering contributing to Typecho! There are many ways to contribute to Typecho, and we appreciate all of them.
## Reporting Bugs
If you find a bug in the source code, you can help us by [submitting an issue](https://github.com/typecho/typecho/issues)
to our [GitHub Repository](https://github.com/typecho/typecho). Even better, you can submit a Pull Request with a fix.
## Contributing Code
If you would like to contribute code to Typecho, please read the following guidelines:
* [Code of Conduct](CODE_OF_CONDUCT.md)
* [Contributing Guide](CONTRIBUTING.md)
* [Coding Style Guide](CODING_STYLE.md)
## Translations
Please see [TRANSLATION](https://github.com/typecho/languages) for details.
## Plugin Development
Please see [Plugin Development](http://docs.typecho.org/plugins) for details.
## Theme Development
Please see [Theme Development](http://docs.typecho.org/themes) for details.
## Community
* [Telegram Channel](https://t.me/typechodev)
* [Homepage](http://typecho.org/)
* [Documents](http://docs.typecho.org/)
* [Community](http://forum.typecho.org/)
* [Download](http://typecho.org/download)

View File

@@ -1,15 +1,30 @@
Typecho Blogging Platform
=========================
####Homepage
http://typecho.org/
Typecho is a PHP-based blog software and is designed to be the most powerful blog engine in the world.
Typecho is released under the GNU General Public License 2.0.
####Document
http://docs.typecho.org/
## Main Features
####Forum
http://forum.typecho.org/
* Multiple databases support (MariaDB, MySQL, SQLite, PostgreSQL)
* Markdown Support
* Plugin Support
* Theme Support
* Custom Fields
* Custom Pages
####Download
http://typecho.org/download
## Requirements
* PHP 7.4.0 or higher
* Database (MariaDB, MySQL, SQLite, PostgreSQL)
* MariaDB or MySQL 5.5.3 or higher
* SQLite 3.7.11 or higher
* PostgreSQL 9.1 or higher
## Screenshots
![Typecho](https://typecho.org/usr/themes/bluecode/img/screenshot/st1.png)
## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

3
SECURITY.md Normal file
View File

@@ -0,0 +1,3 @@
# Security Policy
Vulnerabilities can be reported by emailing security@typecho.org

107
admin/backup.php Normal file
View File

@@ -0,0 +1,107 @@
<?php
include 'common.php';
include 'header.php';
include 'menu.php';
$actionUrl = $security->getTokenUrl(
\Typecho\Router::url('do', array('action' => 'backup', 'widget' => 'Backup'),
\Typecho\Common::url('index.php', $options->rootUrl)));
$backupFiles = \Widget\Backup::alloc()->listFiles();
?>
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12 col-tb-8">
<div id="typecho-welcome">
<form action="<?php echo $actionUrl; ?>" method="post">
<h3><?php _e('备份您的数据'); ?></h3>
<ul>
<li><?php _e('此备份操作仅包含<strong>内容数据</strong>, 并不会涉及任何<strong>设置信息</strong>'); ?></li>
<li><?php _e('如果您的数据量过大, 为了避免操作超时, 建议您直接使用数据库提供的备份工具备份数据'); ?></li>
<li><strong class="warning"><?php _e('为了缩小备份文件体积, 建议您在备份前删除不必要的数据'); ?></strong></li>
</ul>
<p><button class="btn primary" type="submit"><?php _e('开始备份 &raquo;'); ?></button></p>
<input tabindex="1" type="hidden" name="do" value="export">
</form>
</div>
</div>
<div id="backup-secondary" class="col-mb-12 col-tb-4" role="form">
<h3><?php _e('恢复数据'); ?></h3>
<ul class="typecho-option-tabs">
<li class="active w-50"><a href="#from-upload"><?php _e('上传'); ?></a></li>
<li class="w-50"><a href="#from-server"><?php _e('从服务器'); ?></a></li>
</ul>
<form action="<?php echo $actionUrl; ?>" id="from-upload" class="tab-content" method="post" enctype="multipart/form-data">
<ul class="typecho-option">
<li>
<input tabindex="2" id="backup-upload-file" name="file" type="file" class="file">
</li>
</ul>
<ul class="typecho-option typecho-option-submit">
<li>
<button tabindex="4" type="submit" class="btn primary"><?php _e('上传并恢复 &raquo;'); ?></button>
<input type="hidden" name="do" value="import">
</li>
</ul>
</form>
<form action="<?php echo $actionUrl; ?>" id="from-server" class="tab-content hidden" method="post">
<?php if (empty($backupFiles)): ?>
<ul class="typecho-option">
<li>
<p class="description"><?php _e('将备份文件手动上传至服务器的 %s 目录下后, 这里会出现文件选项', __TYPECHO_BACKUP_DIR__); ?></p>
</li>
</ul>
<?php else: ?>
<ul class="typecho-option">
<li>
<label class="typecho-label" for="backup-select-file"><?php _e('选择一个备份文件恢复数据'); ?></label>
<select tabindex="5" name="file" id="backup-select-file">
<?php foreach ($backupFiles as $file): ?>
<option value="<?php echo $file; ?>"><?php echo $file; ?></option>
<?php endforeach; ?>
</select>
</li>
</ul>
<?php endif; ?>
<ul class="typecho-option typecho-option-submit">
<li>
<button tabindex="7" type="submit" class="btn primary"><?php _e('选择并恢复 &raquo;'); ?></button>
<input type="hidden" name="do" value="import">
</li>
</ul>
</form>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';
include 'common-js.php';
include 'form-js.php';
?>
<script>
$('#backup-secondary .typecho-option-tabs li').click(function() {
$('#backup-secondary .typecho-option-tabs li').removeClass('active');
$(this).addClass('active');
$(this).parents('#backup-secondary').find('.tab-content').addClass('hidden');
var selected_tab = $(this).find('a').attr('href');
$(selected_tab).removeClass('hidden');
return false;
});
$('#backup-secondary form').submit(function (e) {
if (!confirm('<?php _e('恢复操作将清除所有现有数据, 是否继续?'); ?>')) {
return false;
}
});
</script>
<?php include 'footer.php'; ?>

View File

@@ -4,16 +4,16 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
<div class="col-mb-12 col-tb-6 col-tb-offset-3">
<?php Typecho_Widget::widget('Widget_Metas_Category_Edit')->form()->render(); ?>
<?php \Widget\Metas\Category\Edit::alloc()->form()->render(); ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -1,19 +1,21 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<script src="<?php $options->adminStaticUrl('js', 'jquery.js?v=' . $suffixVersion); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'jquery-ui.js?v=' . $suffixVersion); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'typecho.js?v=' . $suffixVersion); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'jquery.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'jquery-ui.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'typecho.js'); ?>"></script>
<script>
(function () {
$(document).ready(function() {
// 处理消息机制
(function () {
var prefix = '<?php echo Typecho_Cookie::getPrefix(); ?>',
var prefix = '<?php echo \Typecho\Cookie::getPrefix(); ?>',
cookies = {
notice : $.cookie(prefix + '__typecho_notice'),
noticeType : $.cookie(prefix + '__typecho_notice_type'),
highlight : $.cookie(prefix + '__typecho_notice_highlight')
},
path = '<?php echo Typecho_Cookie::getPath(); ?>';
path = '<?php echo \Typecho\Cookie::getPath(); ?>',
domain = '<?php echo \Typecho\Cookie::getDomain(); ?>',
secure = <?php echo json_encode(\Typecho\Cookie::getSecure()); ?>;
if (!!cookies.notice && 'success|notice|error'.indexOf(cookies.noticeType) >= 0) {
var head = $('.typecho-head-nav'),
@@ -23,31 +25,10 @@
if (head.length > 0) {
p.insertAfter(head);
offset = head.outerHeight();
} else {
p.prependTo(document.body);
}
function checkScroll () {
if ($(window).scrollTop() >= offset) {
p.css({
'position' : 'fixed',
'top' : 0
});
} else {
p.css({
'position' : 'absolute',
'top' : offset
});
}
}
$(window).scroll(function () {
checkScroll();
});
checkScroll();
p.slideDown(function () {
var t = $(this), color = '#C6D880';
@@ -58,46 +39,33 @@
}
t.effect('highlight', {color : color})
.delay(5000).slideUp(function () {
.delay(5000).fadeOut(function () {
$(this).remove();
});
});
$.cookie(prefix + '__typecho_notice', null, {path : path});
$.cookie(prefix + '__typecho_notice_type', null, {path : path});
$.cookie(prefix + '__typecho_notice', null, {path : path, domain: domain, secure: secure});
$.cookie(prefix + '__typecho_notice_type', null, {path : path, domain: domain, secure: secure});
}
if (cookies.highlight) {
$('#' + cookies.highlight).effect('highlight', 1000);
$.cookie(prefix + '__typecho_notice_highlight', null, {path : path});
$.cookie(prefix + '__typecho_notice_highlight', null, {path : path, domain: domain, secure: secure});
}
})();
// 导航菜单 tab 聚焦时展开下拉菜单
(function () {
$('#typecho-nav-list').find('.parent a').focus(function() {
$('#typecho-nav-list').find('.child').hide();
$(this).parents('.root').find('.child').show();
});
$('.operate').find('a').focus(function() {
$('#typecho-nav-list').find('.child').hide();
});
})();
if ($('.typecho-login').length == 0) {
$('a').each(function () {
var t = $(this), href = t.attr('href');
if ((href && href[0] == '#')
|| /^<?php echo preg_quote($options->adminUrl, '/'); ?>.*$/.exec(href)
|| /^<?php echo substr(preg_quote(Typecho_Common::url('s', $options->index), '/'), 0, -1); ?>action\/[_a-zA-Z0-9\/]+.*$/.exec(href)) {
|| /^<?php echo substr(preg_quote(\Typecho\Common::url('s', $options->index), '/'), 0, -1); ?>action\/[_a-zA-Z0-9\/]+.*$/.exec(href)) {
return;
}
t.attr('target', '_blank');
t.attr('target', '_blank')
.attr('rel', 'noopener noreferrer');
});
}
});

View File

@@ -12,15 +12,15 @@ if (!defined('__TYPECHO_ROOT_DIR__') && !@include_once __DIR__ . '/../config.inc
}
/** 初始化组件 */
Typecho_Widget::widget('Widget_Init');
\Widget\Init::alloc();
/** 注册一个初始化插件 */
Typecho_Plugin::factory('admin/common.php')->begin();
\Typecho\Plugin::factory('admin/common.php')->call('begin');
Typecho_Widget::widget('Widget_Options')->to($options);
Typecho_Widget::widget('Widget_User')->to($user);
Typecho_Widget::widget('Widget_Security')->to($security);
Typecho_Widget::widget('Widget_Menu')->to($menu);
\Widget\Options::alloc()->to($options);
\Widget\User::alloc()->to($user);
\Widget\Security::alloc()->to($security);
\Widget\Menu::alloc()->to($menu);
/** 初始化上下文 */
$request = $options->request;
@@ -28,32 +28,27 @@ $response = $options->response;
/** 检测是否是第一次登录 */
$currentMenu = $menu->getCurrentMenu();
list($prefixVersion, $suffixVersion) = explode('/', $options->version);
$params = parse_url($currentMenu[2]);
$adminFile = basename($params['path']);
if (!$user->logged && !Typecho_Cookie::get('__typecho_first_run') && !empty($currentMenu)) {
if ('welcome.php' != $adminFile) {
$response->redirect(Typecho_Common::url('welcome.php', $options->adminUrl));
} else {
Typecho_Cookie::set('__typecho_first_run', 1);
}
} else {
if (!empty($currentMenu)) {
$params = parse_url($currentMenu[2]);
$adminFile = basename($params['path']);
/** 检测版本是否升级 */
if ($user->pass('administrator', true) && !empty($currentMenu)) {
$mustUpgrade = (!defined('Typecho_Common::VERSION') || version_compare(str_replace('/', '.', Typecho_Common::VERSION),
str_replace('/', '.', $options->version), '>'));
if (!$user->logged && !\Typecho\Cookie::get('__typecho_first_run')) {
if ('welcome.php' != $adminFile) {
$response->redirect(\Typecho\Common::url('welcome.php', $options->adminUrl));
} else {
\Typecho\Cookie::set('__typecho_first_run', 1);
}
} elseif ($user->pass('administrator', true)) {
/** 检测版本是否升级 */
$mustUpgrade = version_compare(\Typecho\Common::VERSION, $options->version, '>');
if ($mustUpgrade && 'upgrade.php' != $adminFile) {
$response->redirect(Typecho_Common::url('upgrade.php', $options->adminUrl));
} else if (!$mustUpgrade && 'upgrade.php' == $adminFile) {
if ($mustUpgrade && 'upgrade.php' != $adminFile && 'backup.php' != $adminFile) {
$response->redirect(\Typecho\Common::url('upgrade.php', $options->adminUrl));
} elseif (!$mustUpgrade && 'upgrade.php' == $adminFile) {
$response->redirect($options->adminUrl);
} else if (!$mustUpgrade && 'welcome.php' == $adminFile && $user->logged) {
} elseif (!$mustUpgrade && 'welcome.php' == $adminFile && $user->logged) {
$response->redirect($options->adminUrl);
}
}
}

View File

@@ -1,13 +1,13 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<div class="typecho-foot" role="contentinfo">
<footer class="typecho-foot" role="contentinfo">
<div class="copyright">
<a href="http://typecho.org" class="i-logo-s">Typecho</a>
<p><?php _e('由 <a href="http://typecho.org">%s</a> 强力驱动, 版本 %s (%s)', $options->software, $prefixVersion, $suffixVersion); ?></p>
<a href="https://typecho.org" class="i-logo-s">Typecho</a>
<p><?php _e('由 <a href="https://typecho.org">%s</a> 强力驱动, 版本 %s', $options->software, $options->version); ?></p>
</div>
<nav class="resource">
<a href="http://docs.typecho.org"><?php _e('帮助文档'); ?></a> &bull;
<a href="http://forum.typecho.org"><?php _e('支持论坛'); ?></a> &bull;
<a href="https://docs.typecho.org"><?php _e('帮助文档'); ?></a> &bull;
<a href="https://forum.typecho.org"><?php _e('支持论坛'); ?></a> &bull;
<a href="https://github.com/typecho/typecho/issues"><?php _e('报告错误'); ?></a> &bull;
<a href="http://extends.typecho.org"><?php _e('资源下载'); ?></a>
<a href="https://typecho.org/download"><?php _e('资源下载'); ?></a>
</nav>
</div>
</footer>

File diff suppressed because one or more lines are too long

1
admin/css/install.css Normal file
View File

@@ -0,0 +1 @@
h1{text-align:center}details summary{cursor:pointer}@keyframes fadein{from{opacity:0}to{opacity:1}}.fresh .keep-word{display:none}.keep .fresh-word{display:none}form>.message{display:none;padding:20px;border-radius:5px}.message textarea{width:100%;height:200px;resize:none;margin:10px 0}.message.fade{display:block;animation:fadein .5s linear}.message *:last-child{margin-bottom:0}.message p{margin-top:10px}.message p button{margin-left:5px}.message p button:first-child{margin-left:0}

View File

@@ -1,406 +1,342 @@
/*! normalize.css v2.1.3 | MIT License | git.io/normalize */
/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */
/* ==========================================================================
HTML5 display definitions
/* Document
========================================================================== */
/**
* Correct `block` display not defined in IE 8/9.
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
nav,
section,
summary {
display: block;
}
/**
* Correct `inline-block` display not defined in IE 8/9.
*/
audio,
canvas,
video {
display: inline-block;
}
/**
* Prevent modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/**
* Address `[hidden]` styling not present in IE 8/9.
* Hide the `template` element in IE, Safari, and Firefox < 22.
*/
[hidden],
template {
display: none;
}
/* ==========================================================================
Base
========================================================================== */
/**
* 1. Set default font family to sans-serif.
* 2. Prevent iOS text size adjust after orientation change, without disabling
* user zoom.
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
font-family: sans-serif; /* 1 */
-ms-text-size-adjust: 100%; /* 2 */
-webkit-text-size-adjust: 100%; /* 2 */
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-moz-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove default margin.
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/* ==========================================================================
Links
========================================================================== */
/**
* Remove the gray background color from active links in IE 10.
*/
a {
background: transparent;
margin: 0;
}
/**
* Address `outline` inconsistency between Chrome and other browsers.
*/
a:focus {
outline: thin dotted;
}
/**
* Improve readability when focused and also mouse hovered in all browsers.
*/
a:active,
a:hover {
outline: 0;
}
/* ==========================================================================
Typography
========================================================================== */
/**
* Address variable `h1` font-size and margin within `section` and `article`
* contexts in Firefox 4+, Safari 5, and Chrome.
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* Address styling not present in IE 8/9, Safari 5, and Chrome.
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: 1px dotted;
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bold;
font-weight: bolder;
}
/**
* Address styling not present in Safari 5 and Chrome.
*/
dfn {
font-style: italic;
}
/**
* Address differences between Firefox and other browsers.
*/
hr {
-moz-box-sizing: content-box;
box-sizing: content-box;
height: 0;
}
/**
* Address styling not present in IE 8/9.
*/
mark {
background: #ff0;
color: #000;
}
/**
* Correct font family set oddly in Safari 5 and Chrome.
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
pre,
samp {
font-family: monospace, serif;
font-size: 1em;
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Improve readability of pre-formatted text in all browsers.
*/
pre {
white-space: pre-wrap;
}
/**
* Set consistent quote types.
*/
q {
quotes: "\201C" "\201D" "\2018" "\2019";
}
/**
* Address inconsistent and variable font size in all browsers.
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
font-size: 80%;
}
/**
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
bottom: -0.25em;
}
/* ==========================================================================
Embedded content
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove border when inside `a` element in IE 8/9.
* Remove the border on images inside links in IE 10.
*/
img {
border: 0;
border-style: none;
}
/**
* Correct overflow displayed oddly in IE 9.
*/
svg:not(:root) {
overflow: hidden;
}
/* ==========================================================================
Figures
/* Forms
========================================================================== */
/**
* Address margin not present in IE 8/9 and Safari 5.
*/
figure {
margin: 0;
}
/* ==========================================================================
Forms
========================================================================== */
/**
* Define consistent border, margin, and padding.
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/**
* 1. Correct `color` not being inherited in IE 8/9.
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
*/
legend {
border: 0; /* 1 */
padding: 0; /* 2 */
}
/**
* 1. Correct font family not being inherited in all browsers.
* 2. Correct font size not being inherited in all browsers.
* 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 2 */
margin: 0; /* 3 */
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input {
line-height: normal;
input { /* 1 */
overflow: visible;
}
/**
* Address inconsistent `text-transform` inheritance for `button` and `select`.
* All other form control elements do not inherit `text-transform` values.
* Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
* Correct `select` style inheritance in Firefox 4+ and Opera.
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select {
text-transform: none;
select { /* 1 */
text-transform: none;
}
/**
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Correct inability to style clickable `input` types in iOS.
* 3. Improve usability and consistency of cursor style between image-type
* `input` and others.
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Re-set default cursor for disabled elements.
*/
button[disabled],
html input[disabled] {
cursor: default;
}
/**
* 1. Address box sizing set to `content-box` in IE 8/9/10.
* 2. Remove excess padding in IE 8/9/10.
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
* 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
* (include `-moz` to future-proof).
*/
input[type="search"] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
box-sizing: content-box;
}
/**
* Remove inner padding and search cancel button in Safari 5 and Chrome
* on OS X.
*/
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* Remove inner padding and border in Firefox 4+.
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* 1. Remove default vertical scrollbar in IE 8/9.
* 2. Improve readability and alignment in all browsers.
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto; /* 1 */
vertical-align: top; /* 2 */
overflow: auto;
}
/* ==========================================================================
Tables
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Remove most spacing between table cells.
* Add the correct display in IE 10+.
*/
table {
border-collapse: collapse;
border-spacing: 0;
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

File diff suppressed because one or more lines are too long

View File

@@ -2,41 +2,33 @@
<script>
$(document).ready(function () {
// 自定义字段
$('#custom-field-expand').click(function() {
var btn = $('i', this);
if (btn.hasClass('i-caret-right')) {
btn.removeClass('i-caret-right').addClass('i-caret-down');
} else {
btn.removeClass('i-caret-down').addClass('i-caret-right');
}
$(this).parent().toggleClass('fold');
return false;
});
function attachDeleteEvent (el) {
$('button.btn-xs', el).click(function () {
if (confirm('<?php _e('确认要删除此字段吗?'); ?>')) {
$(this).parents('tr').fadeOut(function () {
$(this).parents('li').fadeOut(function () {
$(this).remove();
});
$(this).parents('form').trigger('change');
}
});
}
$('#custom-field table tbody tr').each(function () {
$('#custom-field .fields .field').each(function () {
attachDeleteEvent(this);
});
$('#custom-field button.operate-add').click(function () {
var html = '<tr><td><input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" class="text-s w-100"></td>'
+ '<td><select name="fieldTypes[]" id="">'
var html = '<li class="field"><div class="field-name"><input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" pattern="^[_a-zA-Z][_a-zA-Z0-9]*$" oninput="this.reportValidity()" class="text-s w-100">'
+ '<select name="fieldTypes[]" id="">'
+ '<option value="str"><?php _e('字符'); ?></option>'
+ '<option value="int"><?php _e('整数'); ?></option>'
+ '<option value="float"><?php _e('小数'); ?></option>'
+ '</select></td>'
+ '<td><textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" class="text-s w-100" rows="2"></textarea></td>'
+ '<td><button type="button" class="btn btn-xs"><?php _e('删除'); ?></button></td></tr>',
el = $(html).hide().appendTo('#custom-field table tbody').fadeIn();
+ '<option value="json"><?php _e('JSON 结构'); ?></option>'
+ '</select></div>'
+ '<div class="field-value"><textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" class="text-s w-100" rows="2"></textarea>'
+ '<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button></div></li>',
el = $(html).hide().appendTo('#custom-field .fields').fadeIn();
attachDeleteEvent(el);
});

View File

@@ -1,73 +1,72 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php if (!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php
$fields = isset($post) ? $post->getFieldItems() : $page->getFieldItems();
$defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaultFieldItems();
?>
<section id="custom-field" class="typecho-post-option<?php if (empty($defaultFields) && empty($fields)): ?> fold<?php endif; ?>">
<label id="custom-field-expand" class="typecho-label"><a href="##"><i class="i-caret-right"></i> <?php _e('自定义字段'); ?></a></label>
<table class="typecho-list-table mono">
<colgroup>
<col width="25%"/>
<col width="10%"/>
<col width="55%"/>
<col width="10%"/>
</colgroup>
<?php foreach ($defaultFields as $field): ?>
<?php list ($label, $input) = $field; ?>
<tr>
<td><?php $label->render(); ?></td>
<td colspan="3"><?php $input->render(); ?></td>
</tr>
<?php endforeach; ?>
<?php foreach ($fields as $field): ?>
<tr>
<td>
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
<input type="text" name="fieldNames[]" value="<?php echo htmlspecialchars($field['name']); ?>" id="fieldname" class="text-s w-100">
</td>
<td>
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
<select name="fieldTypes[]" id="fieldtype">
<option value="str"<?php if ('str' == $field['type']): ?> selected<?php endif; ?>><?php _e('字符'); ?></option>
<option value="int"<?php if ('int' == $field['type']): ?> selected<?php endif; ?>><?php _e('整数'); ?></option>
<option value="float"<?php if ('float' == $field['type']): ?> selected<?php endif; ?>><?php _e('小数'); ?></option>
</select>
</td>
<td>
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
<textarea name="fieldValues[]" id="fieldvalue" class="text-s w-100" rows="2"><?php echo htmlspecialchars($field[$field['type'] . '_value']); ?></textarea>
</td>
<td>
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
</td>
</tr>
<?php endforeach; ?>
<?php if (empty($defaultFields) && empty($fields)): ?>
<tr>
<td>
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
<input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" id="fieldname" class="text-s w-100">
</td>
<td>
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
<select name="fieldTypes[]" id="fieldtype">
<option value="str"><?php _e('字符'); ?></option>
<option value="int"><?php _e('整数'); ?></option>
<option value="float"><?php _e('小数'); ?></option>
</select>
</td>
<td>
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
<textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" id="fieldvalue" class="text-s w-100" rows="2"></textarea>
</td>
<td>
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
</td>
</tr>
<?php endif; ?>
</table>
<div class="description clearfix">
<button type="button" class="btn btn-xs operate-add"><?php _e('+添加字段'); ?></button>
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="http://docs.typecho.org/help/custom-fields">帮助文档</a>'); ?>
</div>
</section>
<details id="custom-field"
class="typecho-post-option" <?php if (!empty($defaultFields) || !empty($fields)): ?>open<?php endif; ?>>
<summary><?php _e('自定义字段'); ?></summary>
<ul class="fields mono">
<?php foreach ($defaultFields as $field): ?>
<?php [$label, $input] = $field; ?>
<li class="field">
<div class="field-name"><?php $label->render(); ?></div>
<div class="field-value"><?php $input->render(); ?></div>
</li>
<?php endforeach; ?>
<?php foreach ($fields as $field): ?>
<li class="field">
<div class="field-name">
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
<input type="text" name="fieldNames[]" value="<?php echo htmlspecialchars($field['name']); ?>"
id="fieldname" pattern="^[_a-zA-Z][_a-zA-Z0-9]*$" oninput="this.reportValidity()" class="text-s w-100">
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
<select name="fieldTypes[]" id="fieldtype">
<option
value="str"<?php if ('str' == $field['type']): ?> selected<?php endif; ?>><?php _e('字符'); ?></option>
<option
value="int"<?php if ('int' == $field['type']): ?> selected<?php endif; ?>><?php _e('整数'); ?></option>
<option
value="float"<?php if ('float' == $field['type']): ?> selected<?php endif; ?>><?php _e('小数'); ?></option>
<option
value="json"<?php if ('json' == $field['type']): ?> selected<?php endif; ?>><?php _e('JSON 结构'); ?></option>
</select>
</div>
<div class="field-value">
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
<textarea name="fieldValues[]" id="fieldvalue" class="text-s w-100"
rows="2"><?php echo htmlspecialchars($field[($field['type'] == 'json' ? 'str' : $field['type']) . '_value']); ?></textarea>
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
</div>
</li>
<?php endforeach; ?>
<?php if (empty($defaultFields) && empty($fields)): ?>
<li class="field">
<div class="field-name">
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
<input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" id="fieldname"
class="text-s w-100" pattern="^[_a-zA-Z][_a-zA-Z0-9]*$" oninput="this.reportValidity()">
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
<select name="fieldTypes[]" id="fieldtype">
<option value="str"><?php _e('字符'); ?></option>
<option value="int"><?php _e('整数'); ?></option>
<option value="float"><?php _e('小数'); ?></option>
<option value="json"><?php _e('JSON 结构'); ?></option>
</select>
</div>
<div class="field-value">
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
<textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" id="fieldvalue"
class="text-s w-100" rows="2"></textarea>
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
</div>
</li>
<?php endif; ?>
</ul>
<div class="add">
<button type="button" class="btn btn-xs operate-add"><?php _e('+添加字段'); ?></button>
<div class="description kit-hidden-mb">
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="https://docs.typecho.org/help/custom-fields">帮助文档</a>'); ?>
</div>
</div>
</details>

View File

@@ -1,15 +1,44 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php $content = !empty($post) ? $post : $page; if ($options->markdown): ?>
<script src="<?php $options->adminStaticUrl('js', 'pagedown.js?v=' . $suffixVersion); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'pagedown-extra.js?v=' . $suffixVersion); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'diff.js?v=' . $suffixVersion); ?>"></script>
<?php $content = !empty($post) ? $post : $page; ?>
<script>
(function () {
$('#text').on('change', function (e) {
e.preventDefault();
e.stopPropagation();
}).on('input', function () {
$(this).parents('form').trigger('write');
});
})();
</script>
<?php if (!$options->markdown): ?>
<script>
(function () {
const textarea = $('#text');
// 原始的插入图片和文件
Typecho.insertFileToEditor = function (file, url, isImage) {
const sel = textarea.getSelection(),
html = isImage ? '<img src="' + url + '" alt="' + file + '" />'
: '<a href="' + url + '">' + file + '</a>',
offset = (sel ? sel.start : 0) + html.length;
textarea.replaceSelection(html);
textarea.setSelection(offset, offset);
};
})();
</script>
<?php else: ?>
<script src="<?php $options->adminStaticUrl('js', 'hyperdown.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'pagedown.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'purify.js'); ?>"></script>
<script>
$(document).ready(function () {
var textarea = $('#text'),
const textarea = $('#text'),
toolbar = $('<div class="editor" id="wmd-button-bar" />').insertBefore(textarea.parent()),
preview = $('<div id="wmd-preview" class="wmd-hidetab" />').insertAfter('.editor');
let isFullScreen = false;
var options = {}, isMarkdown = <?php echo intval($content->isMarkdown || !$content->have()); ?>;
const options = {}, isMarkdown = <?php echo json_encode(!$content->have() || $content->isMarkdown); ?>;
options.strings = {
bold: '<?php _e('加粗'); ?> <strong> Ctrl+B',
@@ -57,31 +86,18 @@ $(document).ready(function () {
help: '<?php _e('Markdown语法帮助'); ?>'
};
var converter = new Markdown.Converter(),
editor = new Markdown.Editor(converter, '', options),
diffMatch = new diff_match_patch(), last = '', preview = $('#wmd-preview'),
mark = '@mark' + Math.ceil(Math.random() * 100000000) + '@',
span = '<span class="diff" />',
cache = {};
Markdown.Extra.init(converter, {
'extensions' : ["tables", "fenced_code_gfm", "def_list", "attr_list", "footnotes", "strikethrough", "newlines"]
});
const converter = new HyperDown(),
editor = new Markdown.Editor(converter, '', options);
// 自动跟随
converter.hooks.chain('postConversion', function (html) {
// clear special html tags
html = html.replace(/<\/?(\!doctype|html|head|body|link|title|input|select|button|textarea|style|noscript)[^>]*>/ig, function (all) {
return all.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/'/g, '&#039;')
.replace(/"/g, '&quot;');
});
// clear hard breaks
html = html.replace(/\s*((?:<br>\n)+)\s*(<\/?(?:p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|li|dd|dt)[^\w])/gm, '$2');
converter.enableHtml(true);
converter.enableLine(true);
const reloadScroll = scrollableEditor(textarea, preview);
// 修正白名单
converter.hook('makeHtml', function (html) {
html = html.replace('<p><!--more--></p>', '<!--more-->');
if (html.indexOf('<!--more-->') > 0) {
var parts = html.split(/\s*<\!\-\-more\-\->\s*/),
summary = parts.shift(),
@@ -91,137 +107,40 @@ $(document).ready(function () {
+ '<div class="details">' + details + '</div>';
}
var diffs = diffMatch.diff_main(last, html);
last = html;
if (diffs.length > 0) {
var stack = [], markStr = mark;
for (var i = 0; i < diffs.length; i ++) {
var diff = diffs[i], op = diff[0], str = diff[1]
sp = str.lastIndexOf('<'), ep = str.lastIndexOf('>');
if (op != 0) {
if (sp >=0 && sp > ep) {
if (op > 0) {
stack.push(str.substring(0, sp) + markStr + str.substring(sp));
} else {
var lastStr = stack[stack.length - 1], lastSp = lastStr.lastIndexOf('<');
stack[stack.length - 1] = lastStr.substring(0, lastSp) + markStr + lastStr.substring(lastSp);
}
} else {
if (op > 0) {
stack.push(str + markStr);
} else {
stack.push(markStr);
}
}
markStr = '';
} else {
stack.push(str);
}
}
html = stack.join('');
if (!markStr) {
var pos = html.indexOf(mark), prev = html.substring(0, pos),
next = html.substr(pos + mark.length),
sp = prev.lastIndexOf('<'), ep = prev.lastIndexOf('>');
if (sp >= 0 && sp > ep) {
html = prev.substring(0, sp) + span + prev.substring(sp) + next;
} else {
html = prev + span + next;
}
}
}
// 替换img
html = html.replace(/<(img)\s+([^>]*)\s*src="([^"]+)"([^>]*)>/ig, function (all, tag, prefix, src, suffix) {
if (!cache[src]) {
cache[src] = false;
} else {
return '<span class="cache" data-width="' + cache[src][0] + '" data-height="' + cache[src][1] + '" '
+ 'style="background:url(' + src + ') no-repeat left top; width:'
+ cache[src][0] + 'px; height:' + cache[src][1] + 'px; display: inline-block; max-width: 100%;'
+ '-webkit-background-size: contain;-moz-background-size: contain;-o-background-size: contain;background-size: contain;" />';
}
return all;
});
// 替换block
html = html.replace(/<(iframe|embed)\s+([^>]*)>/ig, function (all, tag, src) {
if (src[src.length - 1] == '/') {
if (src[src.length - 1] === '/') {
src = src.substring(0, src.length - 1);
}
return '<div style="background: #ddd; height: 40px; overflow: hidden; line-height: 40px; text-align: center; font-size: 12px; color: #777">'
+ tag + ' : ' + $.trim(src) + '</div>';
return '<div class="embed"><strong>'
+ tag + '</strong> : ' + $.trim(src) + '</div>';
});
return html;
return DOMPurify.sanitize(html, {USE_PROFILES: {html: true}});
});
function cacheResize() {
var t = $(this), w = parseInt(t.data('width')), h = parseInt(t.data('height')),
ow = t.width();
t.height(h * ow / w);
}
var to;
editor.hooks.chain('onPreviewRefresh', function () {
var diff = $('.diff', preview), scrolled = false;
const images = $('img', preview);
let count = images.length;
if (to) {
clearTimeout(to);
}
if (count === 0) {
reloadScroll(true);
} else {
images.bind('load error', function () {
count --;
$('img', preview).load(function () {
var t = $(this), src = t.attr('src');
if (scrolled) {
preview.scrollTo(diff, {
offset : - 50
});
}
if (!!src && !cache[src]) {
cache[src] = [this.width, this.height];
}
});
$('.cache', preview).resize(cacheResize).each(cacheResize);
var changed = $('.diff', preview).parent();
if (!changed.is(preview)) {
changed.css('background-color', 'rgba(255,230,0,0.5)');
to = setTimeout(function () {
changed.css('background-color', 'transparent');
}, 4500);
}
if (diff.length > 0) {
var p = diff.position(), lh = diff.parent().css('line-height');
lh = !!lh ? parseInt(lh) : 0;
if (p.top < 0 || p.top > preview.height() - lh) {
preview.scrollTo(diff, {
offset : - 50
});
scrolled = true;
}
if (count === 0) {
reloadScroll(true);
}
});
}
});
<?php Typecho_Plugin::factory('admin/editor-js.php')->markdownEditor($content); ?>
<?php \Typecho\Plugin::factory('admin/editor-js.php')->call('markdownEditor', $content); ?>
var input = $('#text'), th = textarea.height(), ph = preview.height(),
uploadBtn = $('<button type="button" id="btn-fullscreen-upload" class="btn btn-link">'
let th = textarea.height(), ph = preview.height();
const uploadBtn = $('<button type="button" id="btn-fullscreen-upload" class="btn btn-link">'
+ '<i class="i-upload"><?php _e('附件'); ?></i></button>')
.prependTo('.submit .right')
.click(function() {
@@ -238,39 +157,50 @@ $(document).ready(function () {
th = textarea.height();
ph = preview.height();
$(document.body).addClass('fullscreen');
var h = $(window).height() - toolbar.outerHeight();
const h = $(window).height() - toolbar.outerHeight();
textarea.css('height', h);
preview.css('height', h);
isFullScreen = true;
});
editor.hooks.chain('enterFullScreen', function () {
$(document.body).addClass('fullscreen');
var h = window.screen.height - toolbar.outerHeight();
const h = window.screen.height - toolbar.outerHeight();
textarea.css('height', h);
preview.css('height', h);
isFullScreen = true;
});
editor.hooks.chain('exitFullScreen', function () {
$(document.body).removeClass('fullscreen');
textarea.height(th);
preview.height(ph);
isFullScreen = false;
});
editor.hooks.chain('commandExecuted', function () {
textarea.trigger('input');
});
editor.hooks.chain('save', function () {
Typecho.savePost();
});
function initMarkdown() {
editor.run();
var imageButton = $('#wmd-image-button'),
const imageButton = $('#wmd-image-button'),
linkButton = $('#wmd-link-button');
Typecho.insertFileToEditor = function (file, url, isImage) {
var button = isImage ? imageButton : linkButton;
const button = isImage ? imageButton : linkButton;
options.strings[isImage ? 'imagename' : 'linkname'] = file;
button.trigger('click');
var checkDialog = setInterval(function () {
let checkDialog = setInterval(function () {
if ($('.wmd-prompt-dialog').length > 0) {
$('.wmd-prompt-dialog input').val(url).select();
clearInterval(checkDialog);
@@ -279,12 +209,12 @@ $(document).ready(function () {
}, 10);
};
Typecho.uploadComplete = function (file) {
Typecho.insertFileToEditor(file.title, file.url, file.isImage);
Typecho.uploadComplete = function (attachment) {
Typecho.insertFileToEditor(attachment.title, attachment.url, attachment.isImage);
};
// 编辑预览切换
var edittab = $('.editor').prepend('<div class="wmd-edittab"><a href="#wmd-editarea" class="active"><?php _e('撰写'); ?></a><a href="#wmd-preview"><?php _e('预览'); ?></a></div>'),
const edittab = $('.editor').append('<div class="wmd-edittab"><a href="#wmd-editarea" class="active"><?php _e('撰写'); ?></a><a href="#wmd-preview"><?php _e('预览'); ?></a></div>'),
editarea = $(textarea.parent()).attr("id", "wmd-editarea");
$(".wmd-edittab a").click(function() {
@@ -292,11 +222,11 @@ $(document).ready(function () {
$(this).addClass("active");
$("#wmd-editarea, #wmd-preview").addClass("wmd-hidetab");
var selected_tab = $(this).attr("href"),
const selected_tab = $(this).attr("href"),
selected_el = $(selected_tab).removeClass("wmd-hidetab");
// 预览时隐藏编辑器按钮
if (selected_tab == "#wmd-preview") {
if (selected_tab === "#wmd-preview") {
$("#wmd-button-row").addClass("wmd-visualhide");
} else {
$("#wmd-button-row").removeClass("wmd-visualhide");
@@ -307,12 +237,32 @@ $(document).ready(function () {
return false;
});
// 剪贴板复制图片
textarea.bind('paste', function (e) {
const items = (e.clipboardData || e.originalEvent.clipboardData).items;
for (const item of items) {
if (item.kind === 'file') {
const file = item.getAsFile();
if (file.size > 0) {
if (!file.name) {
file.name = (new Date()).toISOString().replace(/\..+$/, '')
+ '.' + file.type.split('/').pop();
}
Typecho.uploadFile(file);
}
}
}
});
}
if (isMarkdown) {
initMarkdown();
} else {
var notice = $('<div class="message notice"><?php _e('这篇文章不是由Markdown语法创建的, 继续使用Markdown编辑它吗?'); ?> '
const notice = $('<div class="message notice"><?php _e('这篇文章不是由Markdown语法创建的, 继续使用Markdown编辑它吗?'); ?> '
+ '<button class="btn btn-xs primary yes"><?php _e('是'); ?></button> '
+ '<button class="btn btn-xs no"><?php _e('否'); ?></button></div>')
.hide().insertBefore(textarea).slideDown();

View File

@@ -1,13 +1,14 @@
<?php
include 'common.php';
$panel = $request->get('panel');
$panelTable = unserialize($options->panelTable);
$panelTable = $options->panelTable;
if (!isset($panelTable['file']) || !in_array(urlencode($panel), $panelTable['file'])) {
throw new Typecho_Plugin_Exception(_t('页面不存在'), 404);
throw new \Typecho\Plugin\Exception(_t('页面不存在'), 404);
}
list ($pluginName, $file) = explode('/', trim($panel, '/'), 2);
[$pluginName, $file] = explode('/', trim($panel, '/'), 2);
require_once $options->pluginDir($pluginName) . '/' . $panel;
require_once $options->pluginDir($pluginName) . '/' . $file;

View File

@@ -1,23 +1,18 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php
if (isset($post) && $post instanceof Typecho_Widget && $post->have()) {
$fileParentContent = $post;
} else if (isset($page) && $page instanceof Typecho_Widget && $page->have()) {
$fileParentContent = $page;
}
$phpMaxFilesize = function_exists('ini_get') ? trim(ini_get('upload_max_filesize')) : '0';
$phpMaxFilesize = function_exists('ini_get') ? trim(ini_get('upload_max_filesize')) : 0;
if (preg_match("/^([0-9]+)([a-z]{1,2})?$/i", $phpMaxFilesize, $matches)) {
$size = intval($matches[1]);
$unit = $matches[2] ?? 'b';
if (preg_match("/^([0-9]+)([a-z]{1,2})$/i", $phpMaxFilesize, $matches)) {
$phpMaxFilesize = strtolower($matches[1] . $matches[2] . (1 == strlen($matches[2]) ? 'b' : ''));
$phpMaxFilesize = round($size * pow(1024, stripos('bkmgtpezy', $unit[0])));
}
?>
<script src="<?php $options->adminStaticUrl('js', 'moxie.js?v=' . $suffixVersion); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'plupload.js?v=' . $suffixVersion); ?>"></script>
<script>
$(document).ready(function() {
function updateAttacmentNumber () {
function updateAttachmentNumber () {
var btn = $('#tab-files-btn'),
balloon = $('.balloon', btn),
count = $('#file-list li .insert').length;
@@ -29,24 +24,40 @@ $(document).ready(function() {
}
balloon.html(count);
} else if (0 == count && balloon.length > 0) {
} else if (0 === count && balloon.length > 0) {
balloon.remove();
}
}
$('.upload-area').bind({
dragenter : function () {
updateAttachmentNumber();
const uploadUrl = $('.upload-area').bind({
dragenter : function (e) {
$(this).parent().addClass('drag');
},
dragover : function (e) {
e.stopPropagation();
e.preventDefault();
$(this).parent().addClass('drag');
},
drop : function () {
drop : function (e) {
e.stopPropagation();
e.preventDefault();
$(this).parent().removeClass('drag');
const files = e.originalEvent.dataTransfer.files;
if (files.length === 0) {
return;
}
for (const file of files) {
Typecho.uploadFile(file);
}
},
dragend : function () {
$(this).parent().removeClass('drag');
},
@@ -54,31 +65,44 @@ $(document).ready(function() {
dragleave : function () {
$(this).parent().removeClass('drag');
}
}).data('url');
const btn = $('.upload-file');
const fileInput = $('<input type="file" name="file" />').hide().insertAfter(btn);
btn.click(function () {
fileInput.click();
return false;
});
updateAttacmentNumber();
fileInput.change(function () {
if (this.files.length === 0) {
return;
}
Typecho.uploadFile(this.files[0]);
});
function fileUploadStart (file) {
$('<li id="' + file.id + '" class="loading">'
+ file.name + '</li>').appendTo('#file-list');
}
function fileUploadError (error) {
var file = error.file, code = error.code, word;
function fileUploadError (type, file) {
let word = '<?php _e('上传出现错误'); ?>';
switch (code) {
case plupload.FILE_SIZE_ERROR:
switch (type) {
case 'size':
word = '<?php _e('文件大小超过限制'); ?>';
break;
case plupload.FILE_EXTENSION_ERROR:
case 'type':
word = '<?php _e('文件扩展名不被支持'); ?>';
break;
case plupload.FILE_DUPLICATE_ERROR:
case 'duplicate':
word = '<?php _e('文件已经上传过'); ?>';
break;
case plupload.HTTP_ERROR:
case 'network':
default:
word = '<?php _e('上传出现错误'); ?>';
break;
}
@@ -94,87 +118,91 @@ $(document).ready(function() {
li.effect('highlight', {color : '#FBC2C4'}, 2000, function () {
$(this).remove();
});
// fix issue #341
plupload.removeFile(file);
}
var completeFile = null;
function fileUploadComplete (id, url, data) {
var li = $('#' + id).removeClass('loading').data('cid', data.cid)
.data('url', data.url)
.data('image', data.isImage)
.html('<input type="hidden" name="attachment[]" value="' + data.cid + '" />'
+ '<a class="insert" target="_blank" href="###" title="<?php _e('点击插入文件'); ?>">' + data.title + '</a><div class="info">' + data.bytes
function fileUploadComplete (file, attachment) {
const li = $('#' + file.id).removeClass('loading').data('cid', attachment.cid)
.data('url', attachment.url)
.data('image', attachment.isImage)
.html('<input type="hidden" name="attachment[]" value="' + attachment.cid + '" />'
+ '<a class="insert" target="_blank" href="###" title="<?php _e('点击插入文件'); ?>">'
+ attachment.title + '</a><div class="info">' + attachment.bytes
+ ' <a class="file" target="_blank" href="<?php $options->adminUrl('media.php'); ?>?cid='
+ data.cid + '" title="<?php _e('编辑'); ?>"><i class="i-edit"></i></a>'
+ attachment.cid + '" title="<?php _e('编辑'); ?>"><i class="i-edit"></i></a>'
+ ' <a class="delete" href="###" title="<?php _e('删除'); ?>"><i class="i-delete"></i></a></div>')
.effect('highlight', 1000);
attachInsertEvent(li);
attachDeleteEvent(li);
updateAttacmentNumber();
updateAttachmentNumber();
if (!completeFile) {
completeFile = data;
}
Typecho.uploadComplete(attachment);
}
$('#tab-files').bind('init', function () {
var uploader = new plupload.Uploader({
browse_button : $('.upload-file').get(0),
url : '<?php $security->index('/action/upload'
. (isset($fileParentContent) ? '?cid=' . $fileParentContent->cid : '')); ?>',
runtimes : 'html5,flash,html4',
flash_swf_url : '<?php $options->adminStaticUrl('js', 'Moxie.swf'); ?>',
drop_element : $('.upload-area').get(0),
filters : {
max_file_size : '<?php echo $phpMaxFilesize ?>',
mime_types : [{'title' : '<?php _e('允许上传的文件'); ?>', 'extensions' : '<?php echo implode(',', $options->allowedAttachmentTypes); ?>'}],
prevent_duplicates : true
},
Typecho.uploadFile = (function () {
const types = '<?php echo json_encode($options->allowedAttachmentTypes); ?>';
const maxSize = <?php echo $phpMaxFilesize ?>;
const queue = [];
let index = 0;
init : {
FilesAdded : function (up, files) {
plupload.each(files, function(file) {
fileUploadStart(file);
});
const getUrl = function () {
const url = new URL(uploadUrl);
const cid = $('input[name=cid]').val();
completeFile = null;
uploader.start();
},
url.searchParams.append('cid', cid);
return url.toString();
};
UploadComplete : function () {
if (completeFile) {
Typecho.uploadComplete(completeFile);
}
},
const upload = function () {
const file = queue.shift();
FileUploaded : function (up, file, result) {
if (200 == result.status) {
var data = $.parseJSON(result.response);
if (data) {
fileUploadComplete(file.id, data[0], data[1]);
plupload.removeFile(file);
return;
}
}
fileUploadError({
code : plupload.HTTP_ERROR,
file : file
});
},
Error : function (up, error) {
fileUploadError(error);
}
if (!file) {
return;
}
});
uploader.init();
});
const data = new FormData();
data.append('file', file);
fetch(getUrl(), {
method: 'POST',
body: data
}).then(function (response) {
if (response.ok) {
return response.json();
} else {
throw new Error(response.statusText);
}
}).then(function (data) {
if (data) {
const [_, attachment] = data;
fileUploadComplete(file, attachment);
upload();
} else {
throw new Error('no data');
}
}).catch(function (error) {
fileUploadError('network', file);
upload();
});
};
return function (file) {
file.id = 'upload-' + (index++);
if (file.size > maxSize) {
return fileUploadError('size', file);
}
const match = file.name.match(/\.([a-z0-9]+)$/i);
if (!match || types.indexOf(match[1].toLowerCase()) < 0) {
return fileUploadError('type', file);
}
queue.push(file);
fileUploadStart(file);
upload();
};
})();
function attachInsertEvent (el) {
$('.insert', el).click(function () {
@@ -194,7 +222,7 @@ $(document).ready(function() {
function () {
$(el).fadeOut(function () {
$(this).remove();
updateAttacmentNumber();
updateAttachmentNumber();
});
});
}

View File

@@ -3,17 +3,19 @@
<?php
if (isset($post) || isset($page)) {
$cid = isset($post) ? $post->cid : $page->cid;
if ($cid) {
Typecho_Widget::widget('Widget_Contents_Attachment_Related', 'parentId=' . $cid)->to($attachment);
\Widget\Contents\Attachment\Related::alloc(['parentId' => $cid])->to($attachment);
} else {
Typecho_Widget::widget('Widget_Contents_Attachment_Unattached')->to($attachment);
\Widget\Contents\Attachment\Unattached::alloc()->to($attachment);
}
}
?>
<div id="upload-panel" class="p">
<div class="upload-area" draggable="true"><?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?></div>
<div class="upload-area" data-url="<?php $security->index('/action/upload'); ?>">
<?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?>
</div>
<ul id="file-list">
<?php while ($attachment->next()): ?>
<li data-cid="<?php $attachment->cid(); ?>" data-url="<?php echo $attachment->attachment->url; ?>" data-image="<?php echo $attachment->attachment->isImage ? 1 : 0; ?>"><input type="hidden" name="attachment[]" value="<?php $attachment->cid(); ?>" />

View File

@@ -1,6 +1,7 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php \Typecho\Plugin::factory('admin/footer.php')->call('begin'); ?>
</body>
</html>
<?php
/** 注册一个结束插件 */
Typecho_Plugin::factory('admin/footer.php')->end();
\Typecho\Plugin::factory('admin/footer.php')->call('end');

View File

@@ -2,25 +2,50 @@
<script>
(function () {
$(document).ready(function () {
var error = $('.typecho-option .error:first');
const error = $('.typecho-option .error:first');
if (error.length > 0) {
$('html,body').scrollTop(error.parents('.typecho-option').offset().top);
}
$('form').submit(function () {
if (this.submitted) {
$('.main form').submit(function () {
const self = $(this);
if (self.hasClass('submitting')) {
return false;
} else {
this.submitted = true;
$('button[type=submit]', this).attr('disabled', 'disabled');
self.addClass('submitting');
}
}).on('submitted', function () {
$('button[type=submit]', this).removeAttr('disabled');
$(this).removeClass('submitting');
});
$('label input[type=text]').click(function (e) {
var check = $('#' + $(this).parents('label').attr('for'));
const check = $('#' + $(this).parents('label').attr('for'));
check.prop('checked', true);
return false;
});
$('.main form input[type="url"]').each(function () {
const self = $(this);
const input = $('<input type="hidden" />').attr('name', self.attr('name'));
function setInput() {
const url = self.val();
try {
const urlObj = new URL(url);
input.val(urlObj.toString());
} catch {
// ignore
}
}
self.removeAttr('name').after(input).on('input', setInput);
setInput();
});
});
})();
</script>

View File

@@ -3,29 +3,21 @@ if (!defined('__TYPECHO_ADMIN__')) {
exit;
}
$header = '<link rel="stylesheet" href="' . Typecho_Common::url('normalize.css?v=' . $suffixVersion, $options->adminStaticUrl('css')) . '">
<link rel="stylesheet" href="' . Typecho_Common::url('grid.css?v=' . $suffixVersion, $options->adminStaticUrl('css')) . '">
<link rel="stylesheet" href="' . Typecho_Common::url('style.css?v=' . $suffixVersion, $options->adminStaticUrl('css')) . '">
<!--[if lt IE 9]>
<script src="' . Typecho_Common::url('html5shiv.js?v=' . $suffixVersion, $options->adminStaticUrl('js')) . '"></script>
<script src="' . Typecho_Common::url('respond.js?v=' . $suffixVersion, $options->adminStaticUrl('js')) . '"></script>
<![endif]-->';
$header = '<link rel="stylesheet" href="' . $options->adminStaticUrl('css', 'normalize.css', true) . '">
<link rel="stylesheet" href="' . $options->adminStaticUrl('css', 'grid.css', true) . '">
<link rel="stylesheet" href="' . $options->adminStaticUrl('css', 'style.css', true) . '">';
/** 注册一个初始化插件 */
$header = Typecho_Plugin::factory('admin/header.php')->header($header);
$header = \Typecho\Plugin::factory('admin/header.php')->filter('header', $header);
?><!DOCTYPE HTML>
<html class="no-js">
<html>
<head>
<meta charset="<?php $options->charset(); ?>">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title><?php _e('%s - %s - Powered by Typecho', $menu->title, $options->title); ?></title>
<meta name="robots" content="noindex, nofollow">
<?php echo $header; ?>
</head>
<body<?php if (isset($bodyClass)) {echo ' class="' . $bodyClass . '"';} ?>>
<!--[if lt IE 9]>
<div class="message error browsehappy" role="dialog"><?php _e('当前网页 <strong>不支持</strong> 你正在使用的浏览器. 为了正常的访问, 请 <a href="http://browsehappy.com/">升级你的浏览器</a>'); ?>.</div>
<![endif]-->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

BIN
admin/img/icons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
admin/img/icons@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -3,72 +3,68 @@ include 'common.php';
include 'header.php';
include 'menu.php';
$stat = Typecho_Widget::widget('Widget_Stat');
$stat = \Widget\Stat::alloc();
?>
<div class="main">
<main class="main">
<div class="container typecho-dashboard">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main">
<div class="col-mb-12 welcome-board" role="main">
<p><?php _e('目前有 <em>%s</em> 篇文章, 并有 <em>%s</em> 条关于你的评论在 <em>%s</em> 个分类中.',
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?>
<br><?php _e('点击下面的链接快速开始:'); ?></p>
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?>
<br><?php _e('点击下面的链接快速开始:'); ?></p>
<ul id="start-link" class="clearfix">
<?php if($user->pass('contributor', true)): ?>
<li><a href="<?php $options->adminUrl('write-post.php'); ?>"><?php _e('撰写新文章'); ?></a></li>
<?php if($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->waitingCommentsNum > 0): ?>
<li><a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核的评论'); ?></a>
<span class="balloon"><?php $stat->waitingCommentsNum(); ?></span>
</li>
<?php elseif($stat->myWaitingCommentsNum > 0): ?>
<li><a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核评论'); ?></a>
<span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
</li>
<?php endif; ?>
<?php if($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->spamCommentsNum > 0): ?>
<li><a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
<span class="balloon"><?php $stat->spamCommentsNum(); ?></span>
</li>
<?php elseif($stat->mySpamCommentsNum > 0): ?>
<li><a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
<span class="balloon"><?php $stat->mySpamCommentsNum(); ?></span>
</li>
<?php endif; ?>
<?php if($user->pass('administrator', true)): ?>
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('更换外观'); ?></a></li>
<li><a href="<?php $options->adminUrl('plugins.php'); ?>"><?php _e('插件管理'); ?></a></li>
<li><a href="<?php $options->adminUrl('options-general.php'); ?>"><?php _e('系统设置'); ?></a></li>
<?php endif; ?>
<ul id="start-link">
<?php if ($user->pass('contributor', true)): ?>
<li><a href="<?php $options->adminUrl('write-post.php'); ?>"><?php _e('撰写新文章'); ?></a></li>
<?php if ($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->waitingCommentsNum > 0): ?>
<li>
<a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核的评论'); ?></a>
<span class="balloon"><?php $stat->waitingCommentsNum(); ?></span>
</li>
<?php elseif ($stat->myWaitingCommentsNum > 0): ?>
<li>
<a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核评论'); ?></a>
<span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
</li>
<?php endif; ?>
<?php if ($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->spamCommentsNum > 0): ?>
<li>
<a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
<span class="balloon"><?php $stat->spamCommentsNum(); ?></span>
</li>
<?php elseif ($stat->mySpamCommentsNum > 0): ?>
<li>
<a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
<span class="balloon"><?php $stat->mySpamCommentsNum(); ?></span>
</li>
<?php endif; ?>
<?php if ($user->pass('administrator', true)): ?>
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('更换外观'); ?></a></li>
<li><a href="<?php $options->adminUrl('plugins.php'); ?>"><?php _e('插件管理'); ?></a></li>
<li><a href="<?php $options->adminUrl('options-general.php'); ?>"><?php _e('系统设置'); ?></a>
</li>
<?php endif; ?>
<?php endif; ?>
<!--<li><a href="<?php $options->adminUrl('profile.php'); ?>"><?php _e('更新我的资料'); ?></a></li>-->
</ul>
<?php $version = Typecho_Cookie::get('__typecho_check_version'); ?>
<?php if ($version && $version['available']): ?>
<div class="update-check">
<p class="message notice">
<?php _e('您当前使用的版本是'); ?> <?php echo $version['current']; ?> &rarr;
<strong><a href="<?php echo $version['link']; ?>"><?php _e('官方最新版本是'); ?> <?php echo $version['latest']; ?></a></strong>
</p>
</div>
<?php endif; ?>
</div>
<div class="col-mb-12 col-tb-4" role="complementary">
<section class="latest-link">
<h3><?php _e('最近发布的文章'); ?></h3>
<?php Typecho_Widget::widget('Widget_Contents_Post_Recent', 'pageSize=10')->to($posts); ?>
<?php \Widget\Contents\Post\Recent::alloc('pageSize=10')->to($posts); ?>
<ul>
<?php if($posts->have()): ?>
<?php while($posts->next()): ?>
<li>
<span><?php $posts->date('n.j'); ?></span>
<a href="<?php $posts->permalink(); ?>" class="title"><?php $posts->title(); ?></a>
</li>
<?php endwhile; ?>
<?php else: ?>
<li><em><?php _e('暂时没有文章'); ?></em></li>
<?php endif; ?>
<?php if ($posts->have()): ?>
<?php while ($posts->next()): ?>
<li>
<span><?php $posts->date('n.j'); ?></span>
<a href="<?php $posts->permalink(); ?>" class="title"><?php $posts->title(); ?></a>
</li>
<?php endwhile; ?>
<?php else: ?>
<li><em><?php _e('暂时没有文章'); ?></em></li>
<?php endif; ?>
</ul>
</section>
</div>
@@ -77,17 +73,18 @@ $stat = Typecho_Widget::widget('Widget_Stat');
<section class="latest-link">
<h3><?php _e('最近得到的回复'); ?></h3>
<ul>
<?php Typecho_Widget::widget('Widget_Comments_Recent', 'pageSize=10')->to($comments); ?>
<?php if($comments->have()): ?>
<?php while($comments->next()): ?>
<li>
<span><?php $comments->date('n.j'); ?></span>
<a href="<?php $comments->permalink(); ?>" class="title"><?php $comments->author(true); ?></a>:
<?php $comments->excerpt(35, '...'); ?>
</li>
<?php endwhile; ?>
<?php \Widget\Comments\Recent::alloc('pageSize=10')->to($comments); ?>
<?php if ($comments->have()): ?>
<?php while ($comments->next()): ?>
<li>
<span><?php $comments->date('n.j'); ?></span>
<a href="<?php $comments->permalink(); ?>"
class="title"><?php $comments->author(false); ?></a>:
<?php $comments->excerpt(35, '...'); ?>
</li>
<?php endwhile; ?>
<?php else: ?>
<li><?php _e('暂时没有回复'); ?></li>
<li><?php _e('暂时没有回复'); ?></li>
<?php endif; ?>
</ul>
</section>
@@ -105,7 +102,7 @@ $stat = Typecho_Widget::widget('Widget_Stat');
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';
@@ -113,47 +110,46 @@ include 'common-js.php';
?>
<script>
$(document).ready(function () {
var ul = $('#typecho-message ul'), cache = window.sessionStorage,
html = cache ? cache.getItem('feed') : '',
update = cache ? cache.getItem('update') : '';
if (!!html) {
ul.html(html);
} else {
html = '';
$.get('<?php $options->index('/action/ajax?do=feed'); ?>', function (o) {
for (var i = 0; i < o.length; i ++) {
var item = o[i];
html += '<li><span>' + item.date + '</span> <a href="' + item.link + '" target="_blank">' + item.title
+ '</a></li>';
}
$(document).ready(function () {
var ul = $('#typecho-message ul'), cache = window.sessionStorage,
html = cache ? cache.getItem('feed') : '',
update = cache ? cache.getItem('update') : '';
if (!!html) {
ul.html(html);
cache.setItem('feed', html);
}, 'json');
}
} else {
html = '';
$.get('<?php $options->index('/action/ajax?do=feed'); ?>', function (o) {
for (var i = 0; i < o.length; i++) {
var item = o[i];
html += '<li><span>' + item.date + '</span> <a href="' + item.link + '" target="_blank">' + item.title
+ '</a></li>';
}
function applyUpdate(update) {
if (update.available) {
$('<div class="update-check"><p>'
+ '<?php _e('您当前使用的版本是 %s'); ?>'.replace('%s', update.current) + '<br />'
+ '<strong><a href="' + update.link + '" target="_blank">'
+ '<?php _e('官方最新版本是 %s'); ?>'.replace('%s', update.latest) + '</a></strong></p></div>')
.appendTo('.welcome-board').effect('highlight');
ul.html(html);
cache.setItem('feed', html);
}, 'json');
}
}
if (!!update) {
applyUpdate($.parseJSON(update));
} else {
update = '';
$.get('<?php $options->index('/action/ajax?do=checkVersion'); ?>', function (o, status, resp) {
applyUpdate(o);
cache.setItem('update', resp.responseText);
}, 'json');
}
});
function applyUpdate(update) {
if (update.available) {
$('<div class="update-check message error"><p>'
+ '<?php _e('您当前使用的版本是 %s'); ?>'.replace('%s', update.current) + '<br />'
+ '<strong><a href="' + update.link + '" target="_blank">'
+ '<?php _e('官方最新版本是 %s'); ?>'.replace('%s', update.latest) + '</a></strong></p></div>')
.insertAfter('.typecho-page-title').effect('highlight');
}
}
if (!!update) {
applyUpdate($.parseJSON(update));
} else {
$.get('<?php $options->index('/action/ajax?do=checkVersion'); ?>', function (o, status, resp) {
applyUpdate(o);
cache.setItem('update', resp.responseText);
}, 'json');
}
});
</script>
<?php include 'footer.php'; ?>

Binary file not shown.

File diff suppressed because it is too large Load Diff

301
admin/js/html5shiv.js vendored
View File

@@ -1,301 +0,0 @@
/**
* @preserve HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
;(function(window, document) {
/*jshint evil:true */
/** version */
var version = '3.7.0';
/** Preset options */
var options = window.html5 || {};
/** Used to skip problem elements */
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
/** Not all elements can be cloned in IE **/
var saveClones = /^(?: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;
/** Detect whether the browser supports default html5 styles */
var supportsHtml5Styles;
/** Name of the expando, to work with multiple documents or to re-shiv one document */
var expando = '_html5shiv';
/** The id for the the documents expando */
var expanID = 0;
/** Cached data for each document */
var expandoData = {};
/** Detect whether the browser supports unknown elements */
var supportsUnknownElements;
(function() {
try {
var a = document.createElement('a');
a.innerHTML = '<xyz></xyz>';
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
supportsHtml5Styles = ('hidden' in a);
supportsUnknownElements = a.childNodes.length == 1 || (function() {
// assign a false positive if unable to shiv
(document.createElement)('a');
var frag = document.createDocumentFragment();
return (
typeof frag.cloneNode == 'undefined' ||
typeof frag.createDocumentFragment == 'undefined' ||
typeof frag.createElement == 'undefined'
);
}());
} catch(e) {
// assign a false positive if detection fails => unable to shiv
supportsHtml5Styles = true;
supportsUnknownElements = true;
}
}());
/*--------------------------------------------------------------------------*/
/**
* Creates a style sheet with the given CSS text and adds it to the document.
* @private
* @param {Document} ownerDocument The document.
* @param {String} cssText The CSS text.
* @returns {StyleSheet} The style element.
*/
function addStyleSheet(ownerDocument, cssText) {
var p = ownerDocument.createElement('p'),
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
p.innerHTML = 'x<style>' + cssText + '</style>';
return parent.insertBefore(p.lastChild, parent.firstChild);
}
/**
* Returns the value of `html5.elements` as an array.
* @private
* @returns {Array} An array of shived element node names.
*/
function getElements() {
var elements = html5.elements;
return typeof elements == 'string' ? elements.split(' ') : elements;
}
/**
* Returns the data associated to the given document
* @private
* @param {Document} ownerDocument The document.
* @returns {Object} An object of data.
*/
function getExpandoData(ownerDocument) {
var data = expandoData[ownerDocument[expando]];
if (!data) {
data = {};
expanID++;
ownerDocument[expando] = expanID;
expandoData[expanID] = data;
}
return data;
}
/**
* returns a shived element for the given nodeName and document
* @memberOf html5
* @param {String} nodeName name of the element
* @param {Document} ownerDocument The context document.
* @returns {Object} The shived element.
*/
function createElement(nodeName, ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createElement(nodeName);
}
if (!data) {
data = getExpandoData(ownerDocument);
}
var node;
if (data.cache[nodeName]) {
node = data.cache[nodeName].cloneNode();
} else if (saveClones.test(nodeName)) {
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
} else {
node = data.createElem(nodeName);
}
// Avoid adding some elements to fragments in IE < 9 because
// * Attributes like `name` or `type` cannot be set/changed once an element
// is inserted into a document/fragment
// * Link elements with `src` attributes that are inaccessible, as with
// a 403 response, will cause the tab/window to crash
// * Script elements appended to fragments will execute when their `src`
// or `text` property is set
return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
}
/**
* returns a shived DocumentFragment for the given document
* @memberOf html5
* @param {Document} ownerDocument The context document.
* @returns {Object} The shived DocumentFragment.
*/
function createDocumentFragment(ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createDocumentFragment();
}
data = data || getExpandoData(ownerDocument);
var clone = data.frag.cloneNode(),
i = 0,
elems = getElements(),
l = elems.length;
for(;i<l;i++){
clone.createElement(elems[i]);
}
return clone;
}
/**
* Shivs the `createElement` and `createDocumentFragment` methods of the document.
* @private
* @param {Document|DocumentFragment} ownerDocument The document.
* @param {Object} data of the document.
*/
function shivMethods(ownerDocument, data) {
if (!data.cache) {
data.cache = {};
data.createElem = ownerDocument.createElement;
data.createFrag = ownerDocument.createDocumentFragment;
data.frag = data.createFrag();
}
ownerDocument.createElement = function(nodeName) {
//abort shiv
if (!html5.shivMethods) {
return data.createElem(nodeName);
}
return createElement(nodeName, ownerDocument, data);
};
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
'var n=f.cloneNode(),c=n.createElement;' +
'h.shivMethods&&(' +
// unroll the `createElement` calls
getElements().join().replace(/[\w\-]+/g, function(nodeName) {
data.createElem(nodeName);
data.frag.createElement(nodeName);
return 'c("' + nodeName + '")';
}) +
');return n}'
)(html5, data.frag);
}
/*--------------------------------------------------------------------------*/
/**
* Shivs the given document.
* @memberOf html5
* @param {Document} ownerDocument The document to shiv.
* @returns {Document} The shived document.
*/
function shivDocument(ownerDocument) {
if (!ownerDocument) {
ownerDocument = document;
}
var data = getExpandoData(ownerDocument);
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
data.hasCSS = !!addStyleSheet(ownerDocument,
// corrects block display not defined in IE6/7/8/9
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
// adds styling not present in IE6/7/8/9
'mark{background:#FF0;color:#000}' +
// hides non-rendered elements
'template{display:none}'
);
}
if (!supportsUnknownElements) {
shivMethods(ownerDocument, data);
}
return ownerDocument;
}
/*--------------------------------------------------------------------------*/
/**
* The `html5` object is exposed so that more elements can be shived and
* existing shiving can be detected on iframes.
* @type Object
* @example
*
* // options can be changed before the script is included
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
*/
var html5 = {
/**
* An array or space separated string of node names of the elements to shiv.
* @memberOf html5
* @type Array|String
*/
'elements': options.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',
/**
* current version of html5shiv
*/
'version': version,
/**
* A flag to indicate that the HTML5 style sheet should be inserted.
* @memberOf html5
* @type Boolean
*/
'shivCSS': (options.shivCSS !== false),
/**
* Is equal to true if a browser supports creating unknown/HTML5 elements
* @memberOf html5
* @type boolean
*/
'supportsUnknownElements': supportsUnknownElements,
/**
* A flag to indicate that the document's `createElement` and `createDocumentFragment`
* methods should be overwritten.
* @memberOf html5
* @type Boolean
*/
'shivMethods': (options.shivMethods !== false),
/**
* A string to describe the type of `html5` object ("default" or "default print").
* @memberOf html5
* @type String
*/
'type': 'default',
// shivs the document according to the specified `html5` object options
'shivDocument': shivDocument,
//creates a shived element
createElement: createElement,
//creates a shived documentFragment
createDocumentFragment: createDocumentFragment
};
/*--------------------------------------------------------------------------*/
// expose html5
window.html5 = html5;
// shiv the document
shivDocument(document);
}(this, document));

1
admin/js/hyperdown.js Normal file

File diff suppressed because one or more lines are too long

4981
admin/js/jquery-ui.js vendored

File diff suppressed because one or more lines are too long

9185
admin/js/jquery.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,875 +0,0 @@
(function () {
// A quick way to make sure we're only keeping span-level tags when we need to.
// This isn't supposed to be foolproof. It's just a quick way to make sure we
// keep all span-level tags returned by a pagedown converter. It should allow
// all span-level tags through, with or without attributes.
var inlineTags = new RegExp(['^(<\\/?(a|abbr|acronym|applet|area|b|basefont|',
'bdo|big|button|cite|code|del|dfn|em|figcaption|',
'font|i|iframe|img|input|ins|kbd|label|map|',
'mark|meter|object|param|progress|q|ruby|rp|rt|s|',
'samp|script|select|small|span|strike|strong|',
'sub|sup|textarea|time|tt|u|var|wbr)[^>]*>|',
'<(br)\\s?\\/?>)$'].join(''), 'i');
/******************************************************************
* Utility Functions *
*****************************************************************/
// patch for ie7
if (!Array.indexOf) {
Array.prototype.indexOf = function(obj) {
for (var i = 0; i < this.length; i++) {
if (this[i] == obj) {
return i;
}
}
return -1;
};
}
function trim(str) {
return str.replace(/^\s+|\s+$/g, '');
}
function rtrim(str) {
return str.replace(/\s+$/g, '');
}
// Remove one level of indentation from text. Indent is 4 spaces.
function outdent(text) {
return text.replace(new RegExp('^(\\t|[ ]{1,4})', 'gm'), '');
}
function contains(str, substr) {
return str.indexOf(substr) != -1;
}
// Sanitize html, removing tags that aren't in the whitelist
function sanitizeHtml(html, whitelist) {
return html.replace(/<[^>]*>?/gi, function(tag) {
return tag.match(whitelist) ? tag : '';
});
}
// Merge two arrays, keeping only unique elements.
function union(x, y) {
var obj = {};
for (var i = 0; i < x.length; i++)
obj[x[i]] = x[i];
for (i = 0; i < y.length; i++)
obj[y[i]] = y[i];
var res = [];
for (var k in obj) {
if (obj.hasOwnProperty(k))
res.push(obj[k]);
}
return res;
}
// JS regexes don't support \A or \Z, so we add sentinels, as Pagedown
// does. In this case, we add the ascii codes for start of text (STX) and
// end of text (ETX), an idea borrowed from:
// https://github.com/tanakahisateru/js-markdown-extra
function addAnchors(text) {
if(text.charAt(0) != '\x02')
text = '\x02' + text;
if(text.charAt(text.length - 1) != '\x03')
text = text + '\x03';
return text;
}
// Remove STX and ETX sentinels.
function removeAnchors(text) {
if(text.charAt(0) == '\x02')
text = text.substr(1);
if(text.charAt(text.length - 1) == '\x03')
text = text.substr(0, text.length - 1);
return text;
}
// Convert markdown within an element, retaining only span-level tags
function convertSpans(text, extra) {
return sanitizeHtml(convertAll(text, extra), inlineTags);
}
// Convert internal markdown using the stock pagedown converter
function convertAll(text, extra) {
var result = extra.blockGamutHookCallback(text);
// We need to perform these operations since we skip the steps in the converter
result = unescapeSpecialChars(result);
result = result.replace(/~D/g, "$$").replace(/~T/g, "~");
result = extra.previousPostConversion(result);
return result;
}
// Convert escaped special characters
function processEscapesStep1(text) {
// Markdown extra adds two escapable characters, `:` and `|`
return text.replace(/\\\|/g, '~I').replace(/\\:/g, '~i');
}
function processEscapesStep2(text) {
return text.replace(/~I/g, '|').replace(/~i/g, ':');
}
// Duplicated from PageDown converter
function unescapeSpecialChars(text) {
// Swap back in all the special characters we've hidden.
text = text.replace(/~E(\d+)E/g, function(wholeMatch, m1) {
var charCodeToReplace = parseInt(m1);
return String.fromCharCode(charCodeToReplace);
});
return text;
}
function slugify(text) {
return text.toLowerCase()
.replace(/\s+/g, '-') // Replace spaces with -
.replace(/[^\w\-]+/g, '') // Remove all non-word chars
.replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text
.replace(/-+$/, ''); // Trim - from end of text
}
/*****************************************************************************
* Markdown.Extra *
****************************************************************************/
Markdown.Extra = function() {
// For converting internal markdown (in tables for instance).
// This is necessary since these methods are meant to be called as
// preConversion hooks, and the Markdown converter passed to init()
// won't convert any markdown contained in the html tags we return.
this.converter = null;
// Stores html blocks we generate in hooks so that
// they're not destroyed if the user is using a sanitizing converter
this.hashBlocks = [];
// Stores footnotes
this.footnotes = {};
this.usedFootnotes = [];
// Special attribute blocks for fenced code blocks and headers enabled.
this.attributeBlocks = false;
// Fenced code block options
this.googleCodePrettify = false;
this.highlightJs = false;
// Table options
this.tableClass = '';
this.tabWidth = 4;
};
Markdown.Extra.init = function(converter, options) {
// Each call to init creates a new instance of Markdown.Extra so it's
// safe to have multiple converters, with different options, on a single page
var extra = new Markdown.Extra();
var postNormalizationTransformations = [];
var preBlockGamutTransformations = [];
var postSpanGamutTransformations = [];
var postConversionTransformations = ["unHashExtraBlocks"];
options = options || {};
options.extensions = options.extensions || ["all"];
if (contains(options.extensions, "all")) {
options.extensions = ["tables", "fenced_code_gfm", "def_list", "attr_list", "footnotes", "smartypants", "strikethrough", "newlines"];
}
preBlockGamutTransformations.push("wrapHeaders");
if (contains(options.extensions, "attr_list")) {
postNormalizationTransformations.push("hashFcbAttributeBlocks");
preBlockGamutTransformations.push("hashHeaderAttributeBlocks");
postConversionTransformations.push("applyAttributeBlocks");
extra.attributeBlocks = true;
}
if (contains(options.extensions, "fenced_code_gfm")) {
// This step will convert fcb inside list items and blockquotes
preBlockGamutTransformations.push("fencedCodeBlocks");
// This extra step is to prevent html blocks hashing and link definition/footnotes stripping inside fcb
postNormalizationTransformations.push("fencedCodeBlocks");
}
if (contains(options.extensions, "tables")) {
preBlockGamutTransformations.push("tables");
}
if (contains(options.extensions, "def_list")) {
preBlockGamutTransformations.push("definitionLists");
}
if (contains(options.extensions, "footnotes")) {
postNormalizationTransformations.push("stripFootnoteDefinitions");
preBlockGamutTransformations.push("doFootnotes");
postConversionTransformations.push("printFootnotes");
}
if (contains(options.extensions, "smartypants")) {
postConversionTransformations.push("runSmartyPants");
}
if (contains(options.extensions, "strikethrough")) {
postSpanGamutTransformations.push("strikethrough");
}
if (contains(options.extensions, "newlines")) {
postSpanGamutTransformations.push("newlines");
}
converter.hooks.chain("postNormalization", function(text) {
return extra.doTransform(postNormalizationTransformations, text) + '\n';
});
converter.hooks.chain("preBlockGamut", function(text, blockGamutHookCallback) {
// Keep a reference to the block gamut callback to run recursively
extra.blockGamutHookCallback = blockGamutHookCallback;
text = processEscapesStep1(text);
text = extra.doTransform(preBlockGamutTransformations, text) + '\n';
text = processEscapesStep2(text);
return text;
});
converter.hooks.chain("postSpanGamut", function(text) {
return extra.doTransform(postSpanGamutTransformations, text);
});
// Keep a reference to the hook chain running before doPostConversion to apply on hashed extra blocks
extra.previousPostConversion = converter.hooks.postConversion;
converter.hooks.chain("postConversion", function(text) {
text = extra.doTransform(postConversionTransformations, text);
// Clear state vars that may use unnecessary memory
extra.hashBlocks = [];
extra.footnotes = {};
extra.usedFootnotes = [];
return text;
});
if ("highlighter" in options) {
extra.googleCodePrettify = options.highlighter === 'prettify';
extra.highlightJs = options.highlighter === 'highlight';
}
if ("table_class" in options) {
extra.tableClass = options.table_class;
}
extra.converter = converter;
// Caller usually won't need this, but it's handy for testing.
return extra;
};
// Do transformations
Markdown.Extra.prototype.doTransform = function(transformations, text) {
for(var i = 0; i < transformations.length; i++)
text = this[transformations[i]](text);
return text;
};
// Return a placeholder containing a key, which is the block's index in the
// hashBlocks array. We wrap our output in a <p> tag here so Pagedown won't.
Markdown.Extra.prototype.hashExtraBlock = function(block) {
return '\n<p>~X' + (this.hashBlocks.push(block) - 1) + 'X</p>\n';
};
Markdown.Extra.prototype.hashExtraInline = function(block) {
return '~X' + (this.hashBlocks.push(block) - 1) + 'X';
};
// Replace placeholder blocks in `text` with their corresponding
// html blocks in the hashBlocks array.
Markdown.Extra.prototype.unHashExtraBlocks = function(text) {
var self = this;
function recursiveUnHash() {
var hasHash = false;
text = text.replace(/(?:<p>)?~X(\d+)X(?:<\/p>)?/g, function(wholeMatch, m1) {
hasHash = true;
var key = parseInt(m1, 10);
return self.hashBlocks[key];
});
if(hasHash === true) {
recursiveUnHash();
}
}
recursiveUnHash();
return text;
};
// Wrap headers to make sure they won't be in def lists
Markdown.Extra.prototype.wrapHeaders = function(text) {
function wrap(text) {
return '\n' + text + '\n';
}
text = text.replace(/^.+[ \t]*\n=+[ \t]*\n+/gm, wrap);
text = text.replace(/^.+[ \t]*\n-+[ \t]*\n+/gm, wrap);
text = text.replace(/^\#{1,6}[ \t]*.+?[ \t]*\#*\n+/gm, wrap);
return text;
};
/******************************************************************
* Attribute Blocks *
*****************************************************************/
// TODO: use sentinels. Should we just add/remove them in doConversion?
// TODO: better matches for id / class attributes
var attrBlock = "\\{[ \\t]*((?:[#.][-_:a-zA-Z0-9]+[ \\t]*)+)\\}";
var hdrAttributesA = new RegExp("^(#{1,6}.*#{0,6})[ \\t]+" + attrBlock + "[ \\t]*(?:\\n|0x03)", "gm");
var hdrAttributesB = new RegExp("^(.*)[ \\t]+" + attrBlock + "[ \\t]*\\n" +
"(?=[\\-|=]+\\s*(?:\\n|0x03))", "gm"); // underline lookahead
var fcbAttributes = new RegExp("^(```[ \\t]*[^{\\s]*)[ \\t]+" + attrBlock + "[ \\t]*\\n" +
"(?=([\\s\\S]*?)\\n```[ \\t]*(\\n|0x03))", "gm");
// Extract headers attribute blocks, move them above the element they will be
// applied to, and hash them for later.
Markdown.Extra.prototype.hashHeaderAttributeBlocks = function(text) {
var self = this;
function attributeCallback(wholeMatch, pre, attr) {
return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n";
}
text = text.replace(hdrAttributesA, attributeCallback); // ## headers
text = text.replace(hdrAttributesB, attributeCallback); // underline headers
return text;
};
// Extract FCB attribute blocks, move them above the element they will be
// applied to, and hash them for later.
Markdown.Extra.prototype.hashFcbAttributeBlocks = function(text) {
// TODO: use sentinels. Should we just add/remove them in doConversion?
// TODO: better matches for id / class attributes
var self = this;
function attributeCallback(wholeMatch, pre, attr) {
return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n";
}
return text.replace(fcbAttributes, attributeCallback);
};
Markdown.Extra.prototype.applyAttributeBlocks = function(text) {
var self = this;
var blockRe = new RegExp('<p>~XX(\\d+)XX</p>[\\s]*' +
'(?:<(h[1-6]|pre)(?: +class="(\\S+)")?(>[\\s\\S]*?</\\2>))', "gm");
text = text.replace(blockRe, function(wholeMatch, k, tag, cls, rest) {
if (!tag) // no following header or fenced code block.
return '';
// get attributes list from hash
var key = parseInt(k, 10);
var attributes = self.hashBlocks[key];
// get id
var id = attributes.match(/#[^\s#.]+/g) || [];
var idStr = id[0] ? ' id="' + id[0].substr(1, id[0].length - 1) + '"' : '';
// get classes and merge with existing classes
var classes = attributes.match(/\.[^\s#.]+/g) || [];
for (var i = 0; i < classes.length; i++) // Remove leading dot
classes[i] = classes[i].substr(1, classes[i].length - 1);
var classStr = '';
if (cls)
classes = union(classes, [cls]);
if (classes.length > 0)
classStr = ' class="' + classes.join(' ') + '"';
return "<" + tag + idStr + classStr + rest;
});
return text;
};
/******************************************************************
* Tables *
*****************************************************************/
// Find and convert Markdown Extra tables into html.
Markdown.Extra.prototype.tables = function(text) {
var self = this;
var leadingPipe = new RegExp(
['^' ,
'[ ]{0,3}' , // Allowed whitespace
'[|]' , // Initial pipe
'(.+)\\n' , // $1: Header Row
'[ ]{0,3}' , // Allowed whitespace
'[|]([ ]*[-:]+[-| :]*)\\n' , // $2: Separator
'(' , // $3: Table Body
'(?:[ ]*[|].*\\n?)*' , // Table rows
')',
'(?:\\n|$)' // Stop at final newline
].join(''),
'gm'
);
var noLeadingPipe = new RegExp(
['^' ,
'[ ]{0,3}' , // Allowed whitespace
'(\\S.*[|].*)\\n' , // $1: Header Row
'[ ]{0,3}' , // Allowed whitespace
'([-:]+[ ]*[|][-| :]*)\\n' , // $2: Separator
'(' , // $3: Table Body
'(?:.*[|].*\\n?)*' , // Table rows
')' ,
'(?:\\n|$)' // Stop at final newline
].join(''),
'gm'
);
text = text.replace(leadingPipe, doTable);
text = text.replace(noLeadingPipe, doTable);
// $1 = header, $2 = separator, $3 = body
function doTable(match, header, separator, body, offset, string) {
// remove any leading pipes and whitespace
header = header.replace(/^ *[|]/m, '');
separator = separator.replace(/^ *[|]/m, '');
body = body.replace(/^ *[|]/gm, '');
// remove trailing pipes and whitespace
header = header.replace(/[|] *$/m, '');
separator = separator.replace(/[|] *$/m, '');
body = body.replace(/[|] *$/gm, '');
// determine column alignments
alignspecs = separator.split(/ *[|] */);
align = [];
for (var i = 0; i < alignspecs.length; i++) {
var spec = alignspecs[i];
if (spec.match(/^ *-+: *$/m))
align[i] = ' align="right"';
else if (spec.match(/^ *:-+: *$/m))
align[i] = ' align="center"';
else if (spec.match(/^ *:-+ *$/m))
align[i] = ' align="left"';
else align[i] = '';
}
// TODO: parse spans in header and rows before splitting, so that pipes
// inside of tags are not interpreted as separators
var headers = header.split(/ *[|] */);
var colCount = headers.length;
// build html
var cls = self.tableClass ? ' class="' + self.tableClass + '"' : '';
var html = ['<table', cls, '>\n', '<thead>\n', '<tr>\n'].join('');
// build column headers.
for (i = 0; i < colCount; i++) {
var headerHtml = convertSpans(trim(headers[i]), self);
html += [" <th", align[i], ">", headerHtml, "</th>\n"].join('');
}
html += "</tr>\n</thead>\n";
// build rows
var rows = body.split('\n');
for (i = 0; i < rows.length; i++) {
if (rows[i].match(/^\s*$/)) // can apply to final row
continue;
// ensure number of rowCells matches colCount
var rowCells = rows[i].split(/ *[|] */);
var lenDiff = colCount - rowCells.length;
for (var j = 0; j < lenDiff; j++)
rowCells.push('');
html += "<tr>\n";
for (j = 0; j < colCount; j++) {
var colHtml = convertSpans(trim(rowCells[j]), self);
html += [" <td", align[j], ">", colHtml, "</td>\n"].join('');
}
html += "</tr>\n";
}
html += "</table>\n";
// replace html with placeholder until postConversion step
return self.hashExtraBlock(html);
}
return text;
};
/******************************************************************
* Footnotes *
*****************************************************************/
// Strip footnote, store in hashes.
Markdown.Extra.prototype.stripFootnoteDefinitions = function(text) {
var self = this;
text = text.replace(
/\n[ ]{0,3}\[\^(.+?)\]\:[ \t]*\n?([\s\S]*?)\n{1,2}((?=\n[ ]{0,3}\S)|$)/g,
function(wholeMatch, m1, m2) {
m1 = slugify(m1);
m2 += "\n";
m2 = m2.replace(/^[ ]{0,3}/g, "");
self.footnotes[m1] = m2;
return "\n";
});
return text;
};
// Find and convert footnotes references.
Markdown.Extra.prototype.doFootnotes = function(text) {
var self = this;
if(self.isConvertingFootnote === true) {
return text;
}
var footnoteCounter = 0;
text = text.replace(/\[\^(.+?)\]/g, function(wholeMatch, m1) {
var id = slugify(m1);
var footnote = self.footnotes[id];
if (footnote === undefined) {
return wholeMatch;
}
footnoteCounter++;
self.usedFootnotes.push(id);
var html = '<a href="#fn:' + id + '" id="fnref:' + id
+ '" title="See footnote" class="footnote">' + footnoteCounter
+ '</a>';
return self.hashExtraInline(html);
});
return text;
};
// Print footnotes at the end of the document
Markdown.Extra.prototype.printFootnotes = function(text) {
var self = this;
if (self.usedFootnotes.length === 0) {
return text;
}
text += '\n\n<div class="footnotes">\n<hr>\n<ol>\n\n';
for(var i=0; i<self.usedFootnotes.length; i++) {
var id = self.usedFootnotes[i];
var footnote = self.footnotes[id];
self.isConvertingFootnote = true;
var formattedfootnote = convertSpans(footnote, self);
delete self.isConvertingFootnote;
text += '<li id="fn:'
+ id
+ '">'
+ formattedfootnote
+ ' <a href="#fnref:'
+ id
+ '" title="Return to article" class="reversefootnote">&#8617;</a></li>\n\n';
}
text += '</ol>\n</div>';
return text;
};
/******************************************************************
* Fenced Code Blocks (gfm) *
******************************************************************/
// Find and convert gfm-inspired fenced code blocks into html.
Markdown.Extra.prototype.fencedCodeBlocks = function(text) {
function encodeCode(code) {
code = code.replace(/&/g, "&amp;");
code = code.replace(/</g, "&lt;");
code = code.replace(/>/g, "&gt;");
// These were escaped by PageDown before postNormalization
code = code.replace(/~D/g, "$$");
code = code.replace(/~T/g, "~");
return code;
}
var self = this;
text = text.replace(/(?:^|\n)```[ \t]*(\S*)[ \t]*\n([\s\S]*?)\n```[ \t]*(?=\n)/g, function(match, m1, m2) {
var language = m1, codeblock = m2;
// adhere to specified options
var preclass = self.googleCodePrettify ? ' class="prettyprint"' : '';
var codeclass = '';
if (language) {
if (self.googleCodePrettify || self.highlightJs) {
// use html5 language- class names. supported by both prettify and highlight.js
codeclass = ' class="language-' + language + '"';
} else {
codeclass = ' class="' + language + '"';
}
}
var html = ['<pre', preclass, '><code', codeclass, '>',
encodeCode(codeblock), '</code></pre>'].join('');
// replace codeblock with placeholder until postConversion step
return self.hashExtraBlock(html);
});
return text;
};
/******************************************************************
* SmartyPants *
******************************************************************/
Markdown.Extra.prototype.educatePants = function(text) {
var self = this;
var result = '';
var blockOffset = 0;
// Here we parse HTML in a very bad manner
text.replace(/(?:<!--[\s\S]*?-->)|(<)([a-zA-Z1-6]+)([^\n]*?>)([\s\S]*?)(<\/\2>)/g, function(wholeMatch, m1, m2, m3, m4, m5, offset) {
var token = text.substring(blockOffset, offset);
result += self.applyPants(token);
self.smartyPantsLastChar = result.substring(result.length - 1);
blockOffset = offset + wholeMatch.length;
if(!m1) {
// Skip commentary
result += wholeMatch;
return;
}
// Skip special tags
if(!/code|kbd|pre|script|noscript|iframe|math|ins|del|pre/i.test(m2)) {
m4 = self.educatePants(m4);
}
else {
self.smartyPantsLastChar = m4.substring(m4.length - 1);
}
result += m1 + m2 + m3 + m4 + m5;
});
var lastToken = text.substring(blockOffset);
result += self.applyPants(lastToken);
self.smartyPantsLastChar = result.substring(result.length - 1);
return result;
};
function revertPants(wholeMatch, m1) {
var blockText = m1;
blockText = blockText.replace(/&\#8220;/g, "\"");
blockText = blockText.replace(/&\#8221;/g, "\"");
blockText = blockText.replace(/&\#8216;/g, "'");
blockText = blockText.replace(/&\#8217;/g, "'");
blockText = blockText.replace(/&\#8212;/g, "---");
blockText = blockText.replace(/&\#8211;/g, "--");
blockText = blockText.replace(/&\#8230;/g, "...");
return blockText;
}
Markdown.Extra.prototype.applyPants = function(text) {
// Dashes
text = text.replace(/---/g, "&#8212;").replace(/--/g, "&#8211;");
// Ellipses
text = text.replace(/\.\.\./g, "&#8230;").replace(/\.\s\.\s\./g, "&#8230;");
// Backticks
text = text.replace(/``/g, "&#8220;").replace (/''/g, "&#8221;");
if(/^'$/.test(text)) {
// Special case: single-character ' token
if(/\S/.test(this.smartyPantsLastChar)) {
return "&#8217;";
}
return "&#8216;";
}
if(/^"$/.test(text)) {
// Special case: single-character " token
if(/\S/.test(this.smartyPantsLastChar)) {
return "&#8221;";
}
return "&#8220;";
}
// Special case if the very first character is a quote
// followed by punctuation at a non-word-break. Close the quotes by brute force:
text = text.replace (/^'(?=[!"#\$\%'()*+,\-.\/:;<=>?\@\[\\]\^_`{|}~]\B)/, "&#8217;");
text = text.replace (/^"(?=[!"#\$\%'()*+,\-.\/:;<=>?\@\[\\]\^_`{|}~]\B)/, "&#8221;");
// Special case for double sets of quotes, e.g.:
// <p>He said, "'Quoted' words in a larger quote."</p>
text = text.replace(/"'(?=\w)/g, "&#8220;&#8216;");
text = text.replace(/'"(?=\w)/g, "&#8216;&#8220;");
// Special case for decade abbreviations (the '80s):
text = text.replace(/'(?=\d{2}s)/g, "&#8217;");
// Get most opening single quotes:
text = text.replace(/(\s|&nbsp;|--|&[mn]dash;|&\#8211;|&\#8212;|&\#x201[34];)'(?=\w)/g, "$1&#8216;");
// Single closing quotes:
text = text.replace(/([^\s\[\{\(\-])'/g, "$1&#8217;");
text = text.replace(/'(?=\s|s\b)/g, "&#8217;");
// Any remaining single quotes should be opening ones:
text = text.replace(/'/g, "&#8216;");
// Get most opening double quotes:
text = text.replace(/(\s|&nbsp;|--|&[mn]dash;|&\#8211;|&\#8212;|&\#x201[34];)"(?=\w)/g, "$1&#8220;");
// Double closing quotes:
text = text.replace(/([^\s\[\{\(\-])"/g, "$1&#8221;");
text = text.replace(/"(?=\s)/g, "&#8221;");
// Any remaining quotes should be opening ones.
text = text.replace(/"/ig, "&#8220;");
return text;
};
// Find and convert markdown extra definition lists into html.
Markdown.Extra.prototype.runSmartyPants = function(text) {
this.smartyPantsLastChar = '';
text = this.educatePants(text);
// Clean everything inside html tags (some of them may have been converted due to our rough html parsing)
text = text.replace(/(<([a-zA-Z1-6]+)\b([^\n>]*?)(\/)?>)/g, revertPants);
return text;
};
/******************************************************************
* Definition Lists *
******************************************************************/
// Find and convert markdown extra definition lists into html.
Markdown.Extra.prototype.definitionLists = function(text) {
var wholeList = new RegExp(
['(\\x02\\n?|\\n\\n)' ,
'(?:' ,
'(' , // $1 = whole list
'(' , // $2
'[ ]{0,3}' ,
'((?:[ \\t]*\\S.*\\n)+)', // $3 = defined term
'\\n?' ,
'[ ]{0,3}:[ ]+' , // colon starting definition
')' ,
'([\\s\\S]+?)' ,
'(' , // $4
'(?=\\0x03)' , // \z
'|' ,
'(?=' ,
'\\n{2,}' ,
'(?=\\S)' ,
'(?!' , // Negative lookahead for another term
'[ ]{0,3}' ,
'(?:\\S.*\\n)+?' , // defined term
'\\n?' ,
'[ ]{0,3}:[ ]+' , // colon starting definition
')' ,
'(?!' , // Negative lookahead for another definition
'[ ]{0,3}:[ ]+' , // colon starting definition
')' ,
')' ,
')' ,
')' ,
')'
].join(''),
'gm'
);
var self = this;
text = addAnchors(text);
text = text.replace(wholeList, function(match, pre, list) {
var result = trim(self.processDefListItems(list));
result = "<dl>\n" + result + "\n</dl>";
return pre + self.hashExtraBlock(result) + "\n\n";
});
return removeAnchors(text);
};
// Process the contents of a single definition list, splitting it
// into individual term and definition list items.
Markdown.Extra.prototype.processDefListItems = function(listStr) {
var self = this;
var dt = new RegExp(
['(\\x02\\n?|\\n\\n+)' , // leading line
'(' , // definition terms = $1
'[ ]{0,3}' , // leading whitespace
'(?![:][ ]|[ ])' , // negative lookahead for a definition
// mark (colon) or more whitespace
'(?:\\S.*\\n)+?' , // actual term (not whitespace)
')' ,
'(?=\\n?[ ]{0,3}:[ ])' // lookahead for following line feed
].join(''), // with a definition mark
'gm'
);
var dd = new RegExp(
['\\n(\\n+)?' , // leading line = $1
'(' , // marker space = $2
'[ ]{0,3}' , // whitespace before colon
'[:][ ]+' , // definition mark (colon)
')' ,
'([\\s\\S]+?)' , // definition text = $3
'(?=\\n*' , // stop at next definition mark,
'(?:' , // next term or end of text
'\\n[ ]{0,3}[:][ ]|' ,
'<dt>|\\x03' , // \z
')' ,
')'
].join(''),
'gm'
);
listStr = addAnchors(listStr);
// trim trailing blank lines:
listStr = listStr.replace(/\n{2,}(?=\\x03)/, "\n");
// Process definition terms.
listStr = listStr.replace(dt, function(match, pre, termsStr) {
var terms = trim(termsStr).split("\n");
var text = '';
for (var i = 0; i < terms.length; i++) {
var term = terms[i];
// process spans inside dt
term = convertSpans(trim(term), self);
text += "\n<dt>" + term + "</dt>";
}
return text + "\n";
});
// Process actual definitions.
listStr = listStr.replace(dd, function(match, leadingLine, markerSpace, def) {
if (leadingLine || def.match(/\n{2,}/)) {
// replace marker with the appropriate whitespace indentation
def = Array(markerSpace.length + 1).join(' ') + def;
// process markdown inside definition
// TODO?: currently doesn't apply extensions
def = outdent(def) + "\n\n";
def = "\n" + convertAll(def, self) + "\n";
} else {
// convert span-level markdown inside definition
def = rtrim(def);
def = convertSpans(outdent(def), self);
}
return "\n<dd>" + def + "</dd>\n";
});
return removeAnchors(listStr);
};
/***********************************************************
* Strikethrough *
************************************************************/
Markdown.Extra.prototype.strikethrough = function(text) {
// Pretty much duplicated from _DoItalicsAndBold
return text.replace(/([\W_]|^)~T~T(?=\S)([^\r]*?\S[\*_]*)~T~T([\W_]|$)/g,
"$1<del>$2</del>$3");
};
/***********************************************************
* New lines *
************************************************************/
Markdown.Extra.prototype.newlines = function(text) {
// We have to ignore already converted newlines and line breaks in sub-list items
return text.replace(/(<(?:br|\/li)>)?\n/g, function(wholeMatch, previousTag) {
return previousTag ? wholeMatch : " <br>\n";
});
};
})();

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

1
admin/js/purify.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,237 +0,0 @@
/*! Respond.js v1.4.2: min/max-width media query polyfill
* Copyright 2013 Scott Jehl
* Licensed under MIT
* http://j.mp/respondjs */
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
(function(w) {
"use strict";
w.matchMedia = w.matchMedia || function(doc, undefined) {
var bool, docElem = doc.documentElement, refNode = docElem.firstElementChild || docElem.firstChild, fakeBody = doc.createElement("body"), div = doc.createElement("div");
div.id = "mq-test-1";
div.style.cssText = "position:absolute;top:-100em";
fakeBody.style.background = "none";
fakeBody.appendChild(div);
return function(q) {
div.innerHTML = '&shy;<style media="' + q + '"> #mq-test-1 { width: 42px; }</style>';
docElem.insertBefore(fakeBody, refNode);
bool = div.offsetWidth === 42;
docElem.removeChild(fakeBody);
return {
matches: bool,
media: q
};
};
}(w.document);
})(this);
(function(w) {
"use strict";
var respond = {};
w.respond = respond;
respond.update = function() {};
var requestQueue = [], xmlHttp = function() {
var xmlhttpmethod = false;
try {
xmlhttpmethod = new w.XMLHttpRequest();
} catch (e) {
xmlhttpmethod = new w.ActiveXObject("Microsoft.XMLHTTP");
}
return function() {
return xmlhttpmethod;
};
}(), ajax = function(url, callback) {
var req = xmlHttp();
if (!req) {
return;
}
req.open("GET", url, true);
req.onreadystatechange = function() {
if (req.readyState !== 4 || req.status !== 200 && req.status !== 304) {
return;
}
callback(req.responseText);
};
if (req.readyState === 4) {
return;
}
req.send(null);
}, isUnsupportedMediaQuery = function(query) {
return query.replace(respond.regex.minmaxwh, "").match(respond.regex.other);
};
respond.ajax = ajax;
respond.queue = requestQueue;
respond.unsupportedmq = isUnsupportedMediaQuery;
respond.regex = {
media: /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,
keyframes: /@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,
comments: /\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,
urls: /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,
findStyles: /@media *([^\{]+)\{([\S\s]+?)$/,
only: /(only\s+)?([a-zA-Z]+)\s?/,
minw: /\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,
maxw: /\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,
minmaxwh: /\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,
other: /\([^\)]*\)/g
};
respond.mediaQueriesSupported = w.matchMedia && w.matchMedia("only all") !== null && w.matchMedia("only all").matches;
if (respond.mediaQueriesSupported) {
return;
}
var doc = w.document, docElem = doc.documentElement, mediastyles = [], rules = [], appendedEls = [], parsedSheets = {}, resizeThrottle = 30, head = doc.getElementsByTagName("head")[0] || docElem, base = doc.getElementsByTagName("base")[0], links = head.getElementsByTagName("link"), lastCall, resizeDefer, eminpx, getEmValue = function() {
var ret, div = doc.createElement("div"), body = doc.body, originalHTMLFontSize = docElem.style.fontSize, originalBodyFontSize = body && body.style.fontSize, fakeUsed = false;
div.style.cssText = "position:absolute;font-size:1em;width:1em";
if (!body) {
body = fakeUsed = doc.createElement("body");
body.style.background = "none";
}
docElem.style.fontSize = "100%";
body.style.fontSize = "100%";
body.appendChild(div);
if (fakeUsed) {
docElem.insertBefore(body, docElem.firstChild);
}
ret = div.offsetWidth;
if (fakeUsed) {
docElem.removeChild(body);
} else {
body.removeChild(div);
}
docElem.style.fontSize = originalHTMLFontSize;
if (originalBodyFontSize) {
body.style.fontSize = originalBodyFontSize;
}
ret = eminpx = parseFloat(ret);
return ret;
}, applyMedia = function(fromResize) {
var name = "clientWidth", docElemProp = docElem[name], currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[name] || docElemProp, styleBlocks = {}, lastLink = links[links.length - 1], now = new Date().getTime();
if (fromResize && lastCall && now - lastCall < resizeThrottle) {
w.clearTimeout(resizeDefer);
resizeDefer = w.setTimeout(applyMedia, resizeThrottle);
return;
} else {
lastCall = now;
}
for (var i in mediastyles) {
if (mediastyles.hasOwnProperty(i)) {
var thisstyle = mediastyles[i], min = thisstyle.minw, max = thisstyle.maxw, minnull = min === null, maxnull = max === null, em = "em";
if (!!min) {
min = parseFloat(min) * (min.indexOf(em) > -1 ? eminpx || getEmValue() : 1);
}
if (!!max) {
max = parseFloat(max) * (max.indexOf(em) > -1 ? eminpx || getEmValue() : 1);
}
if (!thisstyle.hasquery || (!minnull || !maxnull) && (minnull || currWidth >= min) && (maxnull || currWidth <= max)) {
if (!styleBlocks[thisstyle.media]) {
styleBlocks[thisstyle.media] = [];
}
styleBlocks[thisstyle.media].push(rules[thisstyle.rules]);
}
}
}
for (var j in appendedEls) {
if (appendedEls.hasOwnProperty(j)) {
if (appendedEls[j] && appendedEls[j].parentNode === head) {
head.removeChild(appendedEls[j]);
}
}
}
appendedEls.length = 0;
for (var k in styleBlocks) {
if (styleBlocks.hasOwnProperty(k)) {
var ss = doc.createElement("style"), css = styleBlocks[k].join("\n");
ss.type = "text/css";
ss.media = k;
head.insertBefore(ss, lastLink.nextSibling);
if (ss.styleSheet) {
ss.styleSheet.cssText = css;
} else {
ss.appendChild(doc.createTextNode(css));
}
appendedEls.push(ss);
}
}
}, translate = function(styles, href, media) {
var qs = styles.replace(respond.regex.comments, "").replace(respond.regex.keyframes, "").match(respond.regex.media), ql = qs && qs.length || 0;
href = href.substring(0, href.lastIndexOf("/"));
var repUrls = function(css) {
return css.replace(respond.regex.urls, "$1" + href + "$2$3");
}, useMedia = !ql && media;
if (href.length) {
href += "/";
}
if (useMedia) {
ql = 1;
}
for (var i = 0; i < ql; i++) {
var fullq, thisq, eachq, eql;
if (useMedia) {
fullq = media;
rules.push(repUrls(styles));
} else {
fullq = qs[i].match(respond.regex.findStyles) && RegExp.$1;
rules.push(RegExp.$2 && repUrls(RegExp.$2));
}
eachq = fullq.split(",");
eql = eachq.length;
for (var j = 0; j < eql; j++) {
thisq = eachq[j];
if (isUnsupportedMediaQuery(thisq)) {
continue;
}
mediastyles.push({
media: thisq.split("(")[0].match(respond.regex.only) && RegExp.$2 || "all",
rules: rules.length - 1,
hasquery: thisq.indexOf("(") > -1,
minw: thisq.match(respond.regex.minw) && parseFloat(RegExp.$1) + (RegExp.$2 || ""),
maxw: thisq.match(respond.regex.maxw) && parseFloat(RegExp.$1) + (RegExp.$2 || "")
});
}
}
applyMedia();
}, makeRequests = function() {
if (requestQueue.length) {
var thisRequest = requestQueue.shift();
ajax(thisRequest.href, function(styles) {
translate(styles, thisRequest.href, thisRequest.media);
parsedSheets[thisRequest.href] = true;
w.setTimeout(function() {
makeRequests();
}, 0);
});
}
}, ripCSS = function() {
for (var i = 0; i < links.length; i++) {
var sheet = links[i], href = sheet.href, media = sheet.media, isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
if (!!href && isCSS && !parsedSheets[href]) {
if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
translate(sheet.styleSheet.rawCssText, href, media);
parsedSheets[href] = true;
} else {
if (!/^([a-zA-Z:]*\/\/)/.test(href) && !base || href.replace(RegExp.$1, "").split("/")[0] === w.location.host) {
if (href.substring(0, 2) === "//") {
href = w.location.protocol + href;
}
requestQueue.push({
href: href,
media: media
});
}
}
}
}
makeRequests();
};
ripCSS();
respond.update = ripCSS;
respond.getEmValue = getEmValue;
function callMedia() {
applyMedia(true);
}
if (w.addEventListener) {
w.addEventListener("resize", callMedia, false);
} else if (w.attachEvent) {
w.attachEvent("onresize", callMedia);
}
})(this);

File diff suppressed because one or more lines are too long

878
admin/js/tokeninput.js Executable file → Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -4,8 +4,8 @@ include 'common.php';
if ($user->hasLogin()) {
$response->redirect($options->adminUrl);
}
$rememberName = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_name'));
Typecho_Cookie::delete('__typecho_remember_name');
$rememberName = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_name', ''));
\Typecho\Cookie::delete('__typecho_remember_name');
$bodyClass = 'body-100';
@@ -13,22 +13,24 @@ include 'header.php';
?>
<div class="typecho-login-wrap">
<div class="typecho-login">
<h1><a href="http://typecho.org" class="i-logo">Typecho</a></h1>
<h1><a href="https://typecho.org" class="i-logo">Typecho</a></h1>
<form action="<?php $options->loginAction(); ?>" method="post" name="login" role="form">
<p>
<label for="name" class="sr-only"><?php _e('用户名'); ?></label>
<input type="text" id="name" name="name" value="<?php echo $rememberName; ?>" placeholder="<?php _e('用户名'); ?>" class="text-l w-100" autofocus />
<label for="name" class="sr-only"><?php _e('用户名或邮箱'); ?></label>
<input type="text" id="name" name="name" value="<?php echo $rememberName; ?>" placeholder="<?php _e('用户名或邮箱'); ?>" class="text-l w-100" autofocus />
</p>
<p>
<label for="password" class="sr-only"><?php _e('密码'); ?></label>
<input type="password" id="password" name="password" class="text-l w-100" placeholder="<?php _e('密码'); ?>" />
<input type="password" id="password" name="password" class="text-l w-100" placeholder="<?php _e('密码'); ?>" required />
</p>
<p class="submit">
<button type="submit" class="btn btn-l w-100 primary"><?php _e('登录'); ?></button>
<input type="hidden" name="referer" value="<?php echo htmlspecialchars($request->get('referer')); ?>" />
<input type="hidden" name="referer" value="<?php echo $request->filter('html')->get('referer'); ?>" />
</p>
<p>
<label for="remember"><input type="checkbox" name="remember" class="checkbox" value="1" id="remember" /> <?php _e('下次自动登录'); ?></label>
<label for="remember">
<input<?php if(\Typecho\Cookie::get('__typecho_remember_remember')): ?> checked<?php endif; ?> type="checkbox" name="remember" class="checkbox" value="1" id="remember" /> <?php _e('下次自动登录'); ?>
</label>
</p>
</form>

View File

@@ -3,27 +3,35 @@ include 'common.php';
include 'header.php';
include 'menu.php';
Typecho_Widget::widget('Widget_Metas_Category_Admin')->to($categories);
\Widget\Metas\Category\Admin::alloc()->to($categories);
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main manage-metas">
<div class="col-mb-12" role="main">
<form method="post" name="manage_categories" class="operate-form">
<div class="typecho-list-operate clearfix">
<div class="col-mb-12" role="main">
<form method="post" name="manage_categories" class="operate-form">
<div class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('此分类下的所有内容将被删除, 你确认要删除这些分类吗?'); ?>" href="<?php $security->index('/action/metas-category-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<li><a lang="<?php _e('刷新分类可能需要等待较长时间, 你确认要刷新这些分类吗?'); ?>" href="<?php $security->index('/action/metas-category-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a></li>
<li><a lang="<?php _e('此分类下的所有内容将被删除, 你确认要删除这些分类吗?'); ?>"
href="<?php $security->index('/action/metas-category-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
<li><a lang="<?php _e('刷新分类可能需要等待较长时间, 你确认要刷新这些分类吗?'); ?>"
href="<?php $security->index('/action/metas-category-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a>
</li>
<li class="multiline">
<button type="button" class="btn merge btn-s" rel="<?php $security->index('/action/metas-category-edit?do=merge'); ?>"><?php _e('合并到'); ?></button>
<button type="button" class="btn merge btn-s"
rel="<?php $security->index('/action/metas-category-edit?do=merge'); ?>"><?php _e('合并到'); ?></button>
<select name="merge">
<?php $categories->parse('<option value="{mid}">{name}</option>'); ?>
</select>
@@ -36,67 +44,74 @@ Typecho_Widget::widget('Widget_Metas_Category_Admin')->to($categories);
</div>
</div>
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="20"/>
<col width="30%"/>
<col width="15%"/>
<col width="25%"/>
<col width=""/>
<col width="10%"/>
</colgroup>
<thead>
<tr class="nodrag">
<th> </th>
<th><?php _e('名称'); ?></th>
<th><?php _e('子分类'); ?></th>
<th><?php _e('缩略名'); ?></th>
<th> </th>
<th><?php _e('文章数'); ?></th>
</tr>
</thead>
<tbody>
<?php if($categories->have()): ?>
<?php while ($categories->next()): ?>
<table class="typecho-list-table">
<colgroup>
<col width="3%" class="kit-hidden-mb"/>
<col width=""/>
<col width="15%" class="kit-hidden-mb"/>
<col width="20%"/>
<col width="15%"/>
<col width="15%" class="kit-hidden-mb"/>
</colgroup>
<thead>
<tr class="nodrag">
<th class="kit-hidden-mb"></th>
<th><?php _e('名称'); ?></th>
<th><?php _e('子分类'); ?></th>
<th class="kit-hidden-mb"><?php _e('缩略名'); ?></th>
<th></th>
<th class="kit-hidden-mb"><?php _e('文章数'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($categories->have()): ?>
<?php while ($categories->next()): ?>
<tr id="mid-<?php $categories->theId(); ?>">
<td><input type="checkbox" value="<?php $categories->mid(); ?>" name="mid[]"/></td>
<td><a href="<?php $options->adminUrl('category.php?mid=' . $categories->mid); ?>"><?php $categories->name(); ?></a>
<a href="<?php $categories->permalink(); ?>" title="<?php _e('浏览 %s', $categories->name); ?>"><i class="i-exlink"></i></a>
<td class="kit-hidden-mb"><input type="checkbox"
value="<?php $categories->mid(); ?>"
name="mid[]"/></td>
<td>
<a href="<?php $options->adminUrl('category.php?mid=' . $categories->mid); ?>"><?php $categories->name(); ?></a>
<a href="<?php $categories->permalink(); ?>"
title="<?php _e('浏览 %s', $categories->name); ?>"><i class="i-exlink"></i></a>
</td>
<td>
<?php if (count($categories->children) > 0): ?>
<a href="<?php $options->adminUrl('manage-categories.php?parent=' . $categories->mid); ?>"><?php echo _n('一个分类', '%d个分类', count($categories->children)); ?></a>
<?php else: ?>
<a href="<?php $options->adminUrl('category.php?parent=' . $categories->mid); ?>"><?php echo _e('新增'); ?></a>
<?php endif; ?>
<?php if (count($categories->children) > 0): ?>
<a href="<?php $options->adminUrl('manage-categories.php?parent=' . $categories->mid); ?>"><?php echo _n('一个分类', '%d个分类', count($categories->children)); ?></a>
<?php else: ?>
<a href="<?php $options->adminUrl('category.php?parent=' . $categories->mid); ?>"><?php echo _e('新增'); ?></a>
<?php endif; ?>
</td>
<td><?php $categories->slug(); ?></td>
<td class="kit-hidden-mb"><?php $categories->slug(); ?></td>
<td>
<?php if ($options->defaultCategory == $categories->mid): ?>
<?php _e('默认'); ?>
<?php else: ?>
<a class="hidden-by-mouse" href="<?php $security->index('/action/metas-category-edit?do=default&mid=' . $categories->mid); ?>" title="<?php _e('设为默认'); ?>"><?php _e('默认'); ?></a>
<?php endif; ?>
<?php if ($options->defaultCategory == $categories->mid): ?>
<?php _e('默认'); ?>
<?php else: ?>
<a class="hidden-by-mouse"
href="<?php $security->index('/action/metas-category-edit?do=default&mid=' . $categories->mid); ?>"
title="<?php _e('设为默认'); ?>"><?php _e('默认'); ?></a>
<?php endif; ?>
</td>
<td class="kit-hidden-mb"><a
class="balloon-button left size-<?php echo \Typecho\Common::splitByCount($categories->count, 1, 10, 20, 50, 100); ?>"
href="<?php $options->adminUrl('manage-posts.php?category=' . $categories->mid); ?>"><?php $categories->count(); ?></a>
</td>
<td><a class="balloon-button left size-<?php echo Typecho_Common::splitByCount($categories->count, 1, 10, 20, 50, 100); ?>" href="<?php $options->adminUrl('manage-posts.php?category=' . $categories->mid); ?>"><?php $categories->count(); ?></a></td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何分类'); ?></h6></td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</form>
</div>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6" class="none"><?php _e('没有任何分类'); ?></td>
</tr>
<?php endif; ?>
</tbody>
</table>
</form>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';
@@ -104,51 +119,51 @@ include 'common-js.php';
?>
<script type="text/javascript">
(function () {
$(document).ready(function () {
var table = $('.typecho-list-table').tableDnD({
onDrop : function () {
var ids = [];
(function () {
$(document).ready(function () {
var table = $('.typecho-list-table').tableDnD({
onDrop: function () {
var ids = [];
$('input[type=checkbox]', table).each(function () {
ids.push($(this).val());
});
$('input[type=checkbox]', table).each(function () {
ids.push($(this).val());
});
$.post('<?php $security->index('/action/metas-category-edit?do=sort'); ?>',
$.param({mid : ids}));
$.post('<?php $security->index('/action/metas-category-edit?do=sort'); ?>',
$.param({mid: ids}));
$('tr', table).each(function (i) {
if (i % 2) {
$(this).addClass('even');
} else {
$(this).removeClass('even');
}
});
}
$('tr', table).each(function (i) {
if (i % 2) {
$(this).addClass('even');
} else {
$(this).removeClass('even');
}
});
}
});
table.tableSelectable({
checkEl: 'input[type=checkbox]',
rowEl: 'tr',
selectAllEl: '.typecho-table-select-all',
actionEl: '.dropdown-menu a'
});
$('.btn-drop').dropdownMenu({
btnEl: '.dropdown-toggle',
menuEl: '.dropdown-menu'
});
$('.dropdown-menu button.merge').click(function () {
var btn = $(this);
btn.parents('form').attr('action', btn.attr('rel')).submit();
});
<?php if (isset($request->mid)): ?>
$('.typecho-mini-panel').effect('highlight', '#AACB36');
<?php endif; ?>
});
table.tableSelectable({
checkEl : 'input[type=checkbox]',
rowEl : 'tr',
selectAllEl : '.typecho-table-select-all',
actionEl : '.dropdown-menu a'
});
$('.btn-drop').dropdownMenu({
btnEl : '.dropdown-toggle',
menuEl : '.dropdown-menu'
});
$('.dropdown-menu button.merge').click(function () {
var btn = $(this);
btn.parents('form').attr('action', btn.attr('rel')).submit();
});
<?php if (isset($request->mid)): ?>
$('.typecho-mini-panel').effect('highlight', '#AACB36');
<?php endif; ?>
});
})();
})();
</script>
<?php include 'footer.php'; ?>

View File

@@ -3,27 +3,21 @@ include 'common.php';
include 'header.php';
include 'menu.php';
$stat = Typecho_Widget::widget('Widget_Stat');
$comments = Typecho_Widget::widget('Widget_Comments_Admin');
$isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typecho_Cookie::get('__typecho_all_comments'));
$stat = \Widget\Stat::alloc();
$comments = \Widget\Comments\Admin::alloc();
$isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Typecho\Cookie::get('__typecho_all_comments'));
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<div class="clearfix">
<ul class="typecho-option-tabs right">
<?php if($user->pass('editor', true) && !isset($request->cid)): ?>
<li class="<?php if($isAllComments): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_comments=on'); ?>"><?php _e('所有'); ?></a></li>
<li class="<?php if(!$isAllComments): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_comments=off'); ?>"><?php _e('我的'); ?></a></li>
<?php endif; ?>
</ul>
<div class="typecho-list-operate">
<ul class="typecho-option-tabs">
<li<?php if(!isset($request->status) || 'approved' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php'
. (isset($request->cid) ? '?cid=' . $request->cid : '')); ?>"><?php _e('已通过'); ?></a></li>
. (isset($request->cid) ? '?cid=' . $request->filter('encode')->cid : '')); ?>"><?php _e('已通过'); ?></a></li>
<li<?php if('waiting' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php?status=waiting'
. (isset($request->cid) ? '&cid=' . $request->cid : '')); ?>"><?php _e('待审核'); ?>
. (isset($request->cid) ? '&cid=' . $request->filter('encode')->cid : '')); ?>"><?php _e('待审核'); ?>
<?php if(!$isAllComments && $stat->myWaitingCommentsNum > 0 && !isset($request->cid)): ?>
<span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
<?php elseif($isAllComments && $stat->waitingCommentsNum > 0 && !isset($request->cid)): ?>
@@ -33,7 +27,7 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typ
<?php endif; ?>
</a></li>
<li<?php if('spam' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php?status=spam'
. (isset($request->cid) ? '&cid=' . $request->cid : '')); ?>"><?php _e('垃圾'); ?>
. (isset($request->cid) ? '&cid=' . $request->filter('encode')->cid : '')); ?>"><?php _e('垃圾'); ?>
<?php if(!$isAllComments && $stat->mySpamCommentsNum > 0 && !isset($request->cid)): ?>
<span class="balloon"><?php $stat->mySpamCommentsNum(); ?></span>
<?php elseif($isAllComments && $stat->spamCommentsNum > 0 && !isset($request->cid)): ?>
@@ -43,58 +37,62 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typ
<?php endif; ?>
</a></li>
</ul>
<?php if($user->pass('editor', true) && !isset($request->cid)): ?>
<ul class="typecho-option-tabs">
<li class="<?php if($isAllComments): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_comments=on'); ?>"><?php _e('所有'); ?></a></li>
<li class="<?php if(!$isAllComments): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_comments=off'); ?>"><?php _e('我的'); ?></a></li>
</ul>
<?php endif; ?>
</div>
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $security->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $security->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
<?php if('spam' == $request->get('status')): ?>
<button lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></button>
<?php endif; ?>
</div>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $security->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $security->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
<?php if('spam' == $request->get('status')): ?>
<button lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></button>
<?php endif; ?>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords || '' != $request->category): ?>
<a href="<?php $options->adminUrl('manage-comments.php'
. (isset($request->status) || isset($request->cid) ? '?' .
(isset($request->status) ? 'status=' . htmlspecialchars($request->get('status')) : '') .
(isset($request->cid) ? (isset($request->status) ? '&' : '') . 'cid=' . htmlspecialchars($request->get('cid')) : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<?php if(isset($request->status)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('status')); ?>" name="status" />
<?php endif; ?>
<?php if(isset($request->cid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('cid')); ?>" name="cid" />
<?php endif; ?>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords || '' != $request->category): ?>
<a href="<?php $options->adminUrl('manage-comments.php'
. (isset($request->status) || isset($request->cid) ? '?' .
(isset($request->status) ? 'status=' . $request->filter('encode')->status : '') .
(isset($request->cid) ? (isset($request->status) ? '&' : '') . 'cid=' . $request->filter('encode')->cid : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo $request->filter('html')->keywords; ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<?php if(isset($request->status)): ?>
<input type="hidden" value="<?php echo $request->filter('html')->status; ?>" name="status" />
<?php endif; ?>
<?php if(isset($request->cid)): ?>
<input type="hidden" value="<?php echo $request->filter('html')->cid; ?>" name="cid" />
<?php endif; ?>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
<form method="post" name="manage_comments" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="3%"/>
<col width="6%" />
<col width="3%" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden" />
<col width="20%"/>
<col width="71%"/>
</colgroup>
<thead>
<tr>
<th> </th>
<th class="kit-hidden-mb"> </th>
<th><?php _e('作者'); ?></th>
<th> </th>
<th class="kit-hidden-mb"> </th>
<th><?php _e('内容'); ?></th>
</tr>
</thead>
@@ -112,15 +110,15 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typ
'text' => $comments->text
);
echo htmlspecialchars(Json::encode($comment));
echo htmlspecialchars(json_encode($comment));
?>">
<td valign="top">
<td valign="top" class="kit-hidden-mb">
<input type="checkbox" value="<?php $comments->coid(); ?>" name="coid[]"/>
</td>
<td valign="top">
<td valign="top" class="kit-hidden">
<div class="comment-avatar">
<?php if ('comment' == $comments->type): ?>
<?php $comments->gravatar(40); ?>
<?php $comments->gravatar(40, null, true); ?>
<?php endif; ?>
<?php if ('comment' != $comments->type): ?>
<?php _e('引用'); ?>
@@ -131,7 +129,7 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typ
<div class="comment-meta">
<strong class="comment-author"><?php $comments->author(true); ?></strong>
<?php if($comments->mail): ?>
<br /><span><a href="mailto:<?php $comments->mail(); ?>"><?php $comments->mail(); ?></a></span>
<br /><span><a href="<?php $comments->mail(true); ?>"><?php $comments->mail(); ?></a></span>
<?php endif; ?>
<?php if($comments->ip): ?>
<br /><span><?php $comments->ip(); ?></span>
@@ -175,46 +173,43 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typ
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="4"><h6 class="typecho-list-table-title"><?php _e('没有评论') ?></h6></td>
<td colspan="4" class="none"><?php _e('没有评论') ?></td>
</tr>
<?php endif; ?>
</tbody>
</table><!-- end .typecho-list-table -->
</div><!-- end .typecho-table-wrap -->
<?php if(isset($request->cid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('cid')); ?>" name="cid" />
<input type="hidden" value="<?php echo $request->filter('html')->cid; ?>" name="cid" />
<?php endif; ?>
</form><!-- end .operate-form -->
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $security->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $security->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
<?php if('spam' == $request->get('status')): ?>
<button lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></button>
<?php endif; ?>
</div>
</div>
<?php if($comments->have()): ?>
<ul class="typecho-pager">
<?php $comments->pageNav(); ?>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $security->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $security->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
<?php if('spam' == $request->get('status')): ?>
<button lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></button>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
</div>
</div>
<?php if($comments->have()): ?>
<ul class="typecho-pager">
<?php $comments->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
</main>
<?php
include 'copyright.php';
include 'common-js.php';
@@ -279,10 +274,12 @@ $(document).ready(function () {
form.submit(function () {
var t = $(this), tr = t.parents('tr'),
reply = $('<div class="comment-reply-content"></div>').insertAfter($('.comment-content', tr));
reply.html('<p>' + textarea.val() + '</p>');
var html = DOMPurify.sanitize(textarea.val(), {USE_PROFILES: {html: true}});
reply.html('<p>' + html + '</p>');
$.post(t.attr('action'), t.serialize(), function (o) {
reply.html(o.comment.content)
var html = DOMPurify.sanitize(o.comment.content, {USE_PROFILES: {html: true}});
reply.html(html)
.effect('highlight');
}, 'json');
@@ -340,7 +337,7 @@ $(document).ready(function () {
}
});
var html = '<strong class="comment-author">'
var unsafeHTML = '<strong class="comment-author">'
+ (comment.url ? '<a target="_blank" href="' + comment.url + '">'
+ comment.author + '</a>' : comment.author) + '</strong>'
+ ('comment' != comment.type ? '<small><?php _e('引用'); ?></small>' : '')
@@ -348,13 +345,16 @@ $(document).ready(function () {
+ comment.mail + '</a></span>' : '')
+ (comment.ip ? '<br /><span>' + comment.ip + '</span>' : '');
var html = DOMPurify.sanitize(unsafeHTML, {USE_PROFILES: {html: true}});
var content = DOMPurify.sanitize(comment.text, {USE_PROFILES: {html: true}});
$('.comment-meta', oldTr).html(html)
.effect('highlight');
$('.comment-content', oldTr).html('<p>' + comment.text + '</p>');
$('.comment-content', oldTr).html('<p>' + content + '</p>');
oldTr.data('comment', comment);
$.post(t.attr('action'), comment, function (o) {
$('.comment-content', oldTr).html(o.comment.content)
var content = DOMPurify.sanitize(o.comment.content, {USE_PROFILES: {html: true}});
$('.comment-content', oldTr).html('<p>' + content + '</p>')
.effect('highlight');
}, 'json');

View File

@@ -3,116 +3,131 @@ include 'common.php';
include 'header.php';
include 'menu.php';
$stat = Typecho_Widget::widget('Widget_Stat');
$stat = \Widget\Stat::alloc();
$attachments = \Widget\Contents\Attachment\Admin::alloc();
?>
<?php Typecho_Widget::widget('Widget_Contents_Attachment_Admin')->to($attachments); ?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>" href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>"
href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
<button class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>" lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
</div>
<button class="btn btn-s btn-warn btn-operate"
href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>"
lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords): ?>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords): ?>
<a href="<?php $options->adminUrl('manage-medias.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo $request->filter('html')->keywords; ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
<form method="post" name="manage_medias" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table draggable">
<colgroup>
<col width="20"/>
<col width="6%"/>
<col width="30%"/>
<col width=""/>
<col width="3%" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="30%"/>
<col width="" class="kit-hidden-mb"/>
<col width="30%" class="kit-hidden-mb"/>
<col width="16%"/>
</colgroup>
<thead>
<tr>
<th> </th>
<th> </th>
<th><?php _e('文件名'); ?></th>
<th><?php _e('上传者'); ?></th>
<th><?php _e('所属文章'); ?></th>
<th><?php _e('发布日期'); ?></th>
</tr>
<tr>
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('文件名'); ?></th>
<th class="kit-hidden-mb"><?php _e('上传者'); ?></th>
<th class="kit-hidden-mb"><?php _e('所属文章'); ?></th>
<th><?php _e('发布日期'); ?></th>
</tr>
</thead>
<tbody>
<?php if($attachments->have()): ?>
<?php while($attachments->next()): ?>
<?php $mime = Typecho_Common::mimeIconType($attachments->attachment->mime); ?>
<tr id="<?php $attachments->theId(); ?>">
<td><input type="checkbox" value="<?php $attachments->cid(); ?>" name="cid[]"/></td>
<td><a href="<?php $options->adminUrl('manage-comments.php?cid=' . $attachments->cid); ?>" class="balloon-button size-<?php echo Typecho_Common::splitByCount($attachments->commentsNum, 1, 10, 20, 50, 100); ?>"><?php $attachments->commentsNum(); ?></a></td>
<td>
<i class="mime-<?php echo $mime; ?>"></i>
<a href="<?php $options->adminUrl('media.php?cid=' . $attachments->cid); ?>"><?php $attachments->title(); ?></a>
<a href="<?php $attachments->permalink(); ?>" title="<?php _e('浏览 %s', $attachments->title); ?>"><i class="i-exlink"></i></a>
</td>
<td><?php $attachments->author(); ?></td>
<td>
<?php if ($attachments->parentPost->cid): ?>
<a href="<?php $options->adminUrl('write-' . (0 === strpos($attachments->parentPost->type, 'post') ? 'post' : 'page') . '.php?cid=' . $attachments->parentPost->cid); ?>"><?php $attachments->parentPost->title(); ?></a>
<?php else: ?>
<span class="description"><?php _e('未归档'); ?></span>
<?php endif; ?>
</td>
<td><?php $attachments->dateWord(); ?></td>
</tr>
<?php if ($attachments->have()): ?>
<?php while ($attachments->next()): ?>
<?php $mime = \Typecho\Common::mimeIconType($attachments->attachment->mime); ?>
<tr id="<?php $attachments->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox"
value="<?php $attachments->cid(); ?>"
name="cid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-comments.php?cid=' . $attachments->cid); ?>"
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($attachments->commentsNum, 1, 10, 20, 50, 100); ?>"><?php $attachments->commentsNum(); ?></a>
</td>
<td>
<i class="mime-<?php echo $mime; ?>"></i>
<a href="<?php $options->adminUrl('media.php?cid=' . $attachments->cid); ?>"><?php $attachments->title(); ?></a>
<a href="<?php $attachments->permalink(); ?>"
title="<?php _e('浏览 %s', $attachments->title); ?>"><i
class="i-exlink"></i></a>
</td>
<td class="kit-hidden-mb"><?php $attachments->author(); ?></td>
<td class="kit-hidden-mb">
<?php if ($attachments->parentPost->cid): ?>
<a href="<?php $options->adminUrl('write-' . (0 === strpos($attachments->parentPost->type, 'post') ? 'post' : 'page') . '.php?cid=' . $attachments->parentPost->cid); ?>"><?php $attachments->parentPost->title(); ?></a>
<?php else: ?>
<span class="description"><?php _e('未归档'); ?></span>
<?php endif; ?>
</td>
<td><?php $attachments->dateWord(); ?></td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<?php else: ?>
<tr>
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何文件'); ?></h6></td>
<td colspan="6" class="none"><?php _e('没有任何文件'); ?></td>
</tr>
<?php endif; ?>
<?php endif; ?>
</tbody>
</table><!-- end .typecho-list-table -->
</div><!-- end .typecho-table-wrap -->
</form><!-- end .operate-form -->
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>" href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
<button class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>" lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>"
href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
</div>
<?php if($attachments->have()): ?>
<button class="btn btn-s btn-warn btn-operate"
href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>"
lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
</div>
<?php if ($attachments->have()): ?>
<ul class="typecho-pager">
<?php $attachments->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
<?php endif; ?>
</form>
</div>
</div><!-- end .typecho-page-main -->
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -3,103 +3,132 @@ include 'common.php';
include 'header.php';
include 'menu.php';
$stat = Typecho_Widget::widget('Widget_Stat');
$stat = \Widget\Stat::alloc();
$pages = \Widget\Contents\Page\Admin::alloc();
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些页面吗?'); ?>" href="<?php $security->index('/action/contents-page-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些页面吗?'); ?>"
href="<?php $security->index('/action/contents-page-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-page-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-page-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
</li>
</ul>
</div>
</div>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords): ?>
<div class="search" role="search">
<?php $pages->backLink(); ?>
<?php if ('' != $request->keywords): ?>
<a href="<?php $options->adminUrl('manage-pages.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords" />
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo $request->filter('html')->keywords; ?>" name="keywords"/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
<form method="post" name="manage_pages" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="20"/>
<col width="6%"/>
<col width="30%"/>
<col width="30%"/>
<col width=""/>
<col width="3%" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="42%"/>
<col width="18%"/>
<col width="" class="kit-hidden-mb"/>
<col width="16%"/>
</colgroup>
<thead>
<tr class="nodrag">
<th> </th>
<th> </th>
<th><?php _e('标题'); ?></th>
<th><?php _e('缩略名'); ?></th>
<th><?php _e('作者'); ?></th>
<th><?php _e('日期'); ?></th>
</tr>
<tr class="nodrag">
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('标题'); ?></th>
<th><?php _e('子页面'); ?></th>
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
<th><?php _e('日期'); ?></th>
</tr>
</thead>
<tbody>
<?php Typecho_Widget::widget('Widget_Contents_Page_Admin')->to($pages); ?>
<?php if($pages->have()): ?>
<?php while($pages->next()): ?>
<tr id="<?php $pages->theId(); ?>">
<td><input type="checkbox" value="<?php $pages->cid(); ?>" name="cid[]"/></td>
<td><a href="<?php $options->adminUrl('manage-comments.php?cid=' . $pages->cid); ?>" class="balloon-button size-<?php echo Typecho_Common::splitByCount($pages->commentsNum, 1, 10, 20, 50, 100); ?>"><?php $pages->commentsNum(); ?></a></td>
<td>
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"><?php $pages->title(); ?></a>
<?php
if ($pages->hasSaved || 'page_draft' == $pages->type) {
echo '<em class="status">' . _t('草稿') . '</em>';
} else if ('hidden' == $pages->status) {
echo '<em class="status">' . _t('隐藏') . '</em>';
}
?>
<?php if ('page_draft' != $pages->type): ?>
<a href="<?php $pages->permalink(); ?>" title="<?php _e('浏览 %s', htmlspecialchars($pages->title)); ?>"><i class="i-exlink"></i></a>
<?php endif; ?>
</td>
<td><?php $pages->slug(); ?></td>
<td><?php $pages->author(); ?></td>
<td>
<?php if ($pages->hasSaved): ?>
<span class="description">
<?php $modifyDate = new Typecho_Date($pages->modified); ?>
<?php _e('保存于 %s', $modifyDate->word()); ?>
</span>
<?php else: ?>
<?php $pages->dateWord(); ?>
<?php endif; ?>
</td>
</tr>
<?php if ($pages->have()): ?>
<?php while ($pages->next()): ?>
<tr id="<?php $pages->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $pages->cid(); ?>"
name="cid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-comments.php?cid=' . $pages->cid); ?>"
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($pages->commentsNum, 1, 10, 20, 50, 100); ?>"
title="<?php $pages->commentsNum(); ?> <?php _e('评论'); ?>"><?php $pages->commentsNum(); ?></a>
</td>
<td>
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"><?php $pages->title(); ?></a>
<?php
if ('page_draft' == $pages->type) {
echo '<em class="status">' . _t('草稿') . '</em>';
} elseif ($pages->revision) {
echo '<em class="status">' . _t('有修订版') . '</em>';
}
if ('hidden' == $pages->status) {
echo '<em class="status">' . _t('隐藏') . '</em>';
}
?>
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"
title="<?php _e('编辑 %s', htmlspecialchars($pages->title)); ?>"><i
class="i-edit"></i></a>
<?php if ('page_draft' != $pages->type): ?>
<a href="<?php $pages->permalink(); ?>"
title="<?php _e('浏览 %s', htmlspecialchars($pages->title)); ?>"><i
class="i-exlink"></i></a>
<?php endif; ?>
</td>
<td>
<?php if (count($pages->children) > 0): ?>
<a href="<?php $options->adminUrl('manage-pages.php?parent=' . $pages->cid); ?>"><?php echo _n('一个页面', '%d个页面', count($pages->children)); ?></a>
<?php else: ?>
<a href="<?php $options->adminUrl('write-page.php?parent=' . $pages->cid); ?>"><?php echo _e('新增'); ?></a>
<?php endif; ?>
</td>
<td class="kit-hidden-mb"><?php $pages->author(); ?></td>
<td>
<?php if ('page_draft' == $pages->type || $pages->revision): ?>
<span class="description">
<?php $modifyDate = new \Typecho\Date($pages->revision ? $pages->revision['modified'] : $pages->modified); ?>
<?php _e('保存于 %s', $modifyDate->word()); ?>
</span>
<?php else: ?>
<?php $pages->dateWord(); ?>
<?php endif; ?>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<?php else: ?>
<tr>
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何页面'); ?></h6></td>
<td colspan="6" class="none"><?php _e('没有任何页面'); ?></td>
</tr>
<?php endif; ?>
<?php endif; ?>
</tbody>
</table>
</div><!-- end .typecho-table-wrap -->
</form><!-- end .operate-form -->
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
</main>
<?php
include 'copyright.php';
@@ -107,25 +136,25 @@ include 'common-js.php';
include 'table-js.php';
?>
<?php if(!isset($request->status) || 'publish' == $request->get('status')): ?>
<script type="text/javascript">
(function () {
$(document).ready(function () {
var table = $('.typecho-list-table').tableDnD({
onDrop : function () {
var ids = [];
<?php if (!$request->is('keywords')): ?>
<script type="text/javascript">
(function () {
$(document).ready(function () {
var table = $('.typecho-list-table').tableDnD({
onDrop: function () {
var ids = [];
$('input[type=checkbox]', table).each(function () {
ids.push($(this).val());
$('input[type=checkbox]', table).each(function () {
ids.push($(this).val());
});
$.post('<?php $security->index('/action/contents-page-edit?do=sort'); ?>',
$.param({cid: ids}));
}
});
$.post('<?php $security->index('/action/contents-page-edit?do=sort'); ?>',
$.param({cid : ids}));
}
});
});
})();
</script>
});
})();
</script>
<?php endif; ?>
<?php include 'footer.php'; ?>

View File

@@ -3,146 +3,246 @@ include 'common.php';
include 'header.php';
include 'menu.php';
$stat = Typecho_Widget::widget('Widget_Stat');
$stat = \Widget\Stat::alloc();
$posts = \Widget\Contents\Post\Admin::alloc();
$isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == \Typecho\Cookie::get('__typecho_all_posts'));
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>" href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
<div class="typecho-list-operate">
<ul class="typecho-option-tabs">
<li<?php if (!isset($request->status) || 'all' == $request->get('status')): ?> class="current"<?php endif; ?>>
<a href="<?php $options->adminUrl('manage-posts.php'
. (isset($request->uid) ? '?uid=' . $request->filter('encode')->uid : '')); ?>"><?php _e('可用'); ?></a>
</li>
<li<?php if ('waiting' == $request->get('status')): ?> class="current"<?php endif; ?>><a
href="<?php $options->adminUrl('manage-posts.php?status=waiting'
. (isset($request->uid) ? '&uid=' . $request->filter('encode')->uid : '')); ?>"><?php _e('待审核'); ?>
<?php if (!$isAllPosts && $stat->myWaitingPostsNum > 0 && !isset($request->uid)): ?>
<span class="balloon"><?php $stat->myWaitingPostsNum(); ?></span>
<?php elseif ($isAllPosts && $stat->waitingPostsNum > 0 && !isset($request->uid)): ?>
<span class="balloon"><?php $stat->waitingPostsNum(); ?></span>
<?php elseif (isset($request->uid) && $stat->currentWaitingPostsNum > 0): ?>
<span class="balloon"><?php $stat->currentWaitingPostsNum(); ?></span>
<?php endif; ?>
</a></li>
<li<?php if ('draft' == $request->get('status')): ?> class="current"<?php endif; ?>><a
href="<?php $options->adminUrl('manage-posts.php?status=draft'
. (isset($request->uid) ? '&uid=' . $request->filter('encode')->uid : '')); ?>"><?php _e('草稿'); ?>
<?php if (!$isAllPosts && $stat->myDraftPostsNum > 0 && !isset($request->uid)): ?>
<span class="balloon"><?php $stat->myDraftPostsNum(); ?></span>
<?php elseif ($isAllPosts && $stat->draftPostsNum > 0 && !isset($request->uid)): ?>
<span class="balloon"><?php $stat->draftPostsNum(); ?></span>
<?php elseif (isset($request->uid) && $stat->currentDraftPostsNum > 0): ?>
<span class="balloon"><?php $stat->currentDraftPostsNum(); ?></span>
<?php endif; ?>
</a></li>
</ul>
<?php if ($user->pass('editor', true) && !isset($request->uid)): ?>
<ul class="typecho-option-tabs">
<li class="<?php if ($isAllPosts): ?> current<?php endif; ?>"><a
href="<?php echo $request->makeUriByRequest('__typecho_all_posts=on&page=1'); ?>"><?php _e('所有'); ?></a>
</li>
<li class="<?php if (!$isAllPosts): ?> current<?php endif; ?>"><a
href="<?php echo $request->makeUriByRequest('__typecho_all_posts=off&page=1'); ?>"><?php _e('我的'); ?></a>
</li>
</ul>
<?php endif; ?>
</div>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>"
href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
<?php if ($user->pass('editor', true)): ?>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=waiting'); ?>"><?php _e('标记为<strong>%s</strong>', _t('待审核')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=private'); ?>"><?php _e('标记为<strong>%s</strong>', _t('私密')); ?></a>
</li>
<?php endif; ?>
</ul>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords || '' != $request->category): ?>
<a href="<?php $options->adminUrl('manage-posts.php' . (isset($request->uid) ? '?uid=' . htmlspecialchars($request->get('uid')) : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords" />
<select name="category">
<option value=""><?php _e('所有分类'); ?></option>
<?php Typecho_Widget::widget('Widget_Metas_Category_List')->to($category); ?>
<?php while($category->next()): ?>
<option value="<?php $category->mid(); ?>"<?php if($request->get('category') == $category->mid): ?> selected="true"<?php endif; ?>><?php $category->name(); ?></option>
<?php endwhile; ?>
</select>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
<?php if(isset($request->uid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('uid')); ?>" name="uid" />
<?php endif; ?>
</div>
</form>
</div><!-- end .typecho-list-operate -->
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords || '' != $request->category): ?>
<a href="<?php $options->adminUrl('manage-posts.php'
. (isset($request->status) || isset($request->uid) ? '?' .
(isset($request->status) ? 'status=' . $request->filter('encode')->status : '') .
(isset($request->uid) ? (isset($request->status) ? '&' : '') . 'uid=' . $request->filter('encode')->uid : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo $request->filter('html')->keywords; ?>" name="keywords"/>
<select name="category">
<option value=""><?php _e('所有分类'); ?></option>
<?php \Widget\Metas\Category\Rows::alloc()->to($category); ?>
<?php while ($category->next()): ?>
<option
value="<?php $category->mid(); ?>"<?php if ($request->get('category') == $category->mid): ?> selected="true"<?php endif; ?>><?php $category->name(); ?></option>
<?php endwhile; ?>
</select>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
<?php if (isset($request->uid)): ?>
<input type="hidden" value="<?php echo $request->filter('html')->uid; ?>"
name="uid"/>
<?php endif; ?>
<?php if (isset($request->status)): ?>
<input type="hidden" value="<?php echo $request->filter('html')->status; ?>"
name="status"/>
<?php endif; ?>
</div>
</form>
<form method="post" name="manage_posts" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="20"/>
<col width="6%"/>
<col width="3%" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="45%"/>
<col width=""/>
<col width="18%"/>
<col width="" class="kit-hidden-mb"/>
<col width="18%" class="kit-hidden-mb"/>
<col width="16%"/>
</colgroup>
<thead>
<tr>
<th> </th>
<th> </th>
<th><?php _e('标题'); ?></th>
<th><?php _e('作者'); ?></th>
<th><?php _e('分类'); ?></th>
<th><?php _e('日期'); ?></th>
</tr>
<tr>
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('标题'); ?></th>
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
<th class="kit-hidden-mb"><?php _e('分类'); ?></th>
<th><?php _e('日期'); ?></th>
</tr>
</thead>
<tbody>
<?php Typecho_Widget::widget('Widget_Contents_Post_Admin')->to($posts); ?>
<?php if($posts->have()): ?>
<?php while($posts->next()): ?>
<tr id="<?php $posts->theId(); ?>">
<td><input type="checkbox" value="<?php $posts->cid(); ?>" name="cid[]"/></td>
<td><a href="<?php $options->adminUrl('manage-comments.php?cid=' . $posts->cid); ?>" class="balloon-button size-<?php echo Typecho_Common::splitByCount($posts->commentsNum, 1, 10, 20, 50, 100); ?>"><?php $posts->commentsNum(); ?></a></td>
<td>
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"><?php $posts->title(); ?></a>
<?php
if ($posts->hasSaved || 'post_draft' == $posts->type) {
echo '<em class="status">' . _t('草稿') . '</em>';
} else if ('hidden' == $posts->status) {
echo '<em class="status">' . _t('隐藏') . '</em>';
} else if ('waiting' == $posts->status) {
echo '<em class="status">' . _t('待审核') . '</em>';
} else if ('private' == $posts->status) {
echo '<em class="status">' . _t('私密') . '</em>';
} else if ($posts->password) {
echo '<em class="status">' . _t('密码保护') . '</em>';
}
?>
<?php if ('post_draft' != $posts->type): ?>
<a href="<?php $posts->permalink(); ?>" title="<?php _e('浏览 %s', htmlspecialchars($posts->title)); ?>"><i class="i-exlink"></i></a>
<?php endif; ?>
</td>
<td><a href="<?php $options->adminUrl('manage-posts.php?uid=' . $posts->author->uid); ?>"><?php $posts->author(); ?></a></td>
<td><?php $categories = $posts->categories; $length = count($categories); ?>
<?php foreach ($categories as $key => $val): ?>
<?php echo '<a href="';
$options->adminUrl('manage-posts.php?category=' . $val['mid']
. (isset($request->uid) ? '&uid=' . $request->uid : '')
. (isset($request->status) ? '&status=' . $request->status : ''));
echo '">' . $val['name'] . '</a>' . ($key < $length - 1 ? ', ' : ''); ?>
<?php endforeach; ?>
</td>
<td>
<?php if ($posts->hasSaved): ?>
<span class="description">
<?php $modifyDate = new Typecho_Date($posts->modified); ?>
<?php _e('保存于 %s', $modifyDate->word()); ?>
</span>
<?php else: ?>
<?php $posts->dateWord(); ?>
<?php endif; ?>
</td>
</tr>
<?php if ($posts->have()): ?>
<?php while ($posts->next()): ?>
<tr id="<?php $posts->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $posts->cid(); ?>"
name="cid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-comments.php?cid=' . ($posts->parentId ? $posts->parentId : $posts->cid)); ?>"
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($posts->commentsNum, 1, 10, 20, 50, 100); ?>"
title="<?php $posts->commentsNum(); ?> <?php _e('评论'); ?>"><?php $posts->commentsNum(); ?></a>
</td>
<td>
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"><?php $posts->title(); ?></a>
<?php
if ('post_draft' == $posts->type) {
echo '<em class="status">' . _t('草稿') . '</em>';
} elseif ($posts->revision) {
echo '<em class="status">' . _t('有修订版') . '</em>';
}
if ('hidden' == $posts->status) {
echo '<em class="status">' . _t('隐藏') . '</em>';
} elseif ('waiting' == $posts->status) {
echo '<em class="status">' . _t('待审核') . '</em>';
} elseif ('private' == $posts->status) {
echo '<em class="status">' . _t('私密') . '</em>';
} elseif ($posts->password) {
echo '<em class="status">' . _t('密码保护') . '</em>';
}
?>
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"
title="<?php _e('编辑 %s', htmlspecialchars($posts->title)); ?>"><i
class="i-edit"></i></a>
<?php if ('post_draft' != $posts->type): ?>
<a href="<?php $posts->permalink(); ?>"
title="<?php _e('浏览 %s', htmlspecialchars($posts->title)); ?>"><i
class="i-exlink"></i></a>
<?php endif; ?>
</td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-posts.php?__typecho_all_posts=off&uid=' . $posts->author->uid); ?>"><?php $posts->author(); ?></a>
</td>
<td class="kit-hidden-mb"><?php foreach($posts->categories as $index => $category): ?><!--
--><?php echo ($index > 0 ? ', ' : '') . '<a href="';
$options->adminUrl('manage-posts.php?category=' . $category['mid']
. (isset($request->uid) ? '&uid=' . $request->filter('encode')->uid : '')
. (isset($request->status) ? '&status=' . $request->filter('encode')->status : ''));
echo '">' . $category['name'] . '</a>'; ?><!--
--><?php endforeach; ?>
</td>
<td>
<?php if ('post_draft' == $posts->type || $posts->revision): ?>
<span class="description">
<?php $modifyDate = new \Typecho\Date($posts->revision ? $posts->revision['modified'] : $posts->modified); ?>
<?php _e('保存于 %s', $modifyDate->word()); ?>
</span>
<?php else: ?>
<?php $posts->dateWord(); ?>
<?php endif; ?>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<?php else: ?>
<tr>
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何文章'); ?></h6></td>
<td colspan="6" class="none"><?php _e('没有任何文章'); ?></td>
</tr>
<?php endif; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</form><!-- end .operate-form -->
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>" href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>"
href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
<?php if ($user->pass('editor', true)): ?>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=waiting'); ?>"><?php _e('标记为<strong>%s</strong>', _t('待审核')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=private'); ?>"><?php _e('标记为<strong>%s</strong>', _t('私密')); ?></a>
</li>
<?php endif; ?>
</ul>
</div>
</div>
<?php if($posts->have()): ?>
<?php if ($posts->have()): ?>
<ul class="typecho-pager">
<?php $posts->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
<?php endif; ?>
</form>
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -3,57 +3,70 @@ include 'common.php';
include 'header.php';
include 'menu.php';
Typecho_Widget::widget('Widget_Metas_Tag_Admin')->to($tags);
\Widget\Metas\Tag\Admin::alloc()->to($tags);
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main manage-metas">
<div class="col-mb-12 col-tb-8" role="main">
<form method="post" name="manage_tags" class="operate-form">
<div class="typecho-list-operate clearfix">
<div class="col-mb-12 col-tb-8" role="main">
<form method="post" name="manage_tags" class="operate-form">
<div class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些标签吗?'); ?>" href="<?php $security->index('/action/metas-tag-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<li><a lang="<?php _e('刷新标签可能需要等待较长时间, 你确认要刷新这些标签吗?'); ?>" href="<?php $security->index('/action/metas-tag-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a></li>
<li class="multiline">
<button type="button" class="btn btn-s merge" rel="<?php $security->index('/action/metas-tag-edit?do=merge'); ?>"><?php _e('合并到'); ?></button>
<input type="text" name="merge" class="text-s" />
</li>
</ul>
</div>
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些标签吗?'); ?>"
href="<?php $security->index('/action/metas-tag-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
<li><a lang="<?php _e('刷新标签可能需要等待较长时间, 你确认要刷新这些标签吗?'); ?>"
href="<?php $security->index('/action/metas-tag-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a>
</li>
<li class="multiline">
<button type="button" class="btn btn-s merge"
rel="<?php $security->index('/action/metas-tag-edit?do=merge'); ?>"><?php _e('合并到'); ?></button>
<input type="text" name="merge" class="text-s"/>
</li>
</ul>
</div>
</div>
</div>
<ul class="typecho-list-notable tag-list clearfix">
<?php if($tags->have()): ?>
<?php while ($tags->next()): ?>
<li class="size-<?php $tags->split(5, 10, 20, 30); ?>" id="<?php $tags->theId(); ?>">
<input type="checkbox" value="<?php $tags->mid(); ?>" name="mid[]"/>
<span rel="<?php echo $request->makeUriByRequest('mid=' . $tags->mid); ?>"><?php $tags->name(); ?></span>
<a class="tag-edit-link" href="<?php echo $request->makeUriByRequest('mid=' . $tags->mid); ?>"><i class="i-edit"></i></a>
</li>
<?php endwhile; ?>
<?php else: ?>
<h6 class="typecho-list-table-title"><?php _e('没有任何标签'); ?></h6>
<?php endif; ?>
</ul>
<input type="hidden" name="do" value="delete" />
</form>
</div>
<div class="col-mb-12 col-tb-4" role="form">
<?php Typecho_Widget::widget('Widget_Metas_Tag_Edit')->form()->render(); ?>
</div>
<?php if ($tags->have()): ?>
<ul class="typecho-list-notable tag-list">
<?php while ($tags->next()): ?>
<li class="size-<?php $tags->split(5, 10, 20, 30); ?>" id="<?php $tags->theId(); ?>">
<input type="checkbox" value="<?php $tags->mid(); ?>" name="mid[]"/>
<span
rel="<?php echo $request->makeUriByRequest('mid=' . $tags->mid); ?>"><?php $tags->name(); ?></span>
<a class="tag-edit-link"
href="<?php echo $request->makeUriByRequest('mid=' . $tags->mid); ?>"><i
class="i-edit"></i></a>
</li>
<?php endwhile; ?>
</ul>
<?php else: ?>
<ul class="tag-list">
<li class="none"><?php _e('没有任何标签'); ?></li>
</ul>
<?php endif; ?>
<input type="hidden" name="do" value="delete"/>
</form>
</div>
<div class="col-mb-12 col-tb-4" role="form">
<?php \Widget\Metas\Tag\Edit::alloc()->form()->render(); ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';
@@ -61,31 +74,31 @@ include 'common-js.php';
?>
<script type="text/javascript">
(function () {
$(document).ready(function () {
(function () {
$(document).ready(function () {
$('.typecho-list-notable').tableSelectable({
checkEl : 'input[type=checkbox]',
rowEl : 'li',
selectAllEl : '.typecho-table-select-all',
actionEl : '.dropdown-menu a'
$('.typecho-list-notable').tableSelectable({
checkEl: 'input[type=checkbox]',
rowEl: 'li',
selectAllEl: '.typecho-table-select-all',
actionEl: '.dropdown-menu a'
});
$('.btn-drop').dropdownMenu({
btnEl: '.dropdown-toggle',
menuEl: '.dropdown-menu'
});
$('.dropdown-menu button.merge').click(function () {
var btn = $(this);
btn.parents('form').attr('action', btn.attr('rel')).submit();
});
<?php if (isset($request->mid)): ?>
$('.typecho-mini-panel').effect('highlight', '#AACB36');
<?php endif; ?>
});
$('.btn-drop').dropdownMenu({
btnEl : '.dropdown-toggle',
menuEl : '.dropdown-menu'
});
$('.dropdown-menu button.merge').click(function () {
var btn = $(this);
btn.parents('form').attr('action', btn.attr('rel')).submit();
});
<?php if (isset($request->mid)): ?>
$('.typecho-mini-panel').effect('highlight', '#AACB36');
<?php endif; ?>
});
})();
})();
</script>
<?php include 'footer.php'; ?>

View File

@@ -2,113 +2,128 @@
include 'common.php';
include 'header.php';
include 'menu.php';
$users = \Widget\Users\Admin::alloc();
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>" href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>"
href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
</div>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords): ?>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords): ?>
<a href="<?php $options->adminUrl('manage-users.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords" />
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo $request->filter('html')->keywords; ?>" name="keywords"/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
<form method="post" name="manage_users" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="20"/>
<col width="6%"/>
<col width="3%" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="30%"/>
<col width=""/>
<col width="25%"/>
<col width="" class="kit-hidden-mb"/>
<col width="25%" class="kit-hidden-mb"/>
<col width="15%"/>
</colgroup>
<thead>
<tr>
<th> </th>
<th> </th>
<th><?php _e('用户名'); ?></th>
<th><?php _e('昵称'); ?></th>
<th><?php _e('电子邮件'); ?></th>
<th><?php _e('用户组'); ?></th>
</tr>
<tr>
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('用户名'); ?></th>
<th class="kit-hidden-mb"><?php _e('昵称'); ?></th>
<th class="kit-hidden-mb"><?php _e('电子邮件'); ?></th>
<th><?php _e('用户组'); ?></th>
</tr>
</thead>
<tbody>
<?php Typecho_Widget::widget('Widget_Users_Admin')->to($users); ?>
<?php while($users->next()): ?>
<?php while ($users->next()): ?>
<tr id="user-<?php $users->uid(); ?>">
<td><input type="checkbox" value="<?php $users->uid(); ?>" name="uid[]"/></td>
<td><a href="<?php $options->adminUrl('manage-posts.php?uid=' . $users->uid); ?>" class="balloon-button left size-<?php echo Typecho_Common::splitByCount($users->postsNum, 1, 10, 20, 50, 100); ?>"><?php $users->postsNum(); ?></a></td>
<td><a href="<?php $options->adminUrl('user.php?uid=' . $users->uid); ?>"><?php $users->name(); ?></a>
<a href="<?php $users->permalink(); ?>" title="<?php _e('浏览 %s', $users->screenName); ?>"><i class="i-exlink"></i></a>
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $users->uid(); ?>"
name="uid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-posts.php?__typecho_all_posts=off&uid=' . $users->uid); ?>"
class="balloon-button left size-<?php echo \Typecho\Common::splitByCount($users->postsNum, 1, 10, 20, 50, 100); ?>"><?php $users->postsNum(); ?></a>
</td>
<td>
<a href="<?php $options->adminUrl('user.php?uid=' . $users->uid); ?>"><?php $users->name(); ?></a>
<a href="<?php $users->permalink(); ?>"
title="<?php _e('浏览 %s', $users->screenName); ?>"><i
class="i-exlink"></i></a>
</td>
<td class="kit-hidden-mb"><?php $users->screenName(); ?></td>
<td class="kit-hidden-mb"><?php if ($users->mail): ?><a
href="mailto:<?php $users->mail(); ?>"><?php $users->mail(); ?></a><?php else: _e('暂无'); endif; ?>
</td>
<td><?php $users->screenName(); ?></td>
<td><?php if($users->mail): ?><a href="mailto:<?php $users->mail(); ?>"><?php $users->mail(); ?></a><?php else: _e('暂无'); endif; ?></td>
<td><?php switch ($users->group) {
case 'administrator':
_e('管理员');
break;
case 'editor':
_e('编辑');
break;
case 'contributor':
_e('贡献者');
break;
case 'subscriber':
_e('关注者');
break;
case 'visitor':
_e('访问者');
break;
default:
break;
} ?></td>
case 'administrator':
_e('管理员');
break;
case 'editor':
_e('编辑');
break;
case 'contributor':
_e('贡献者');
break;
case 'subscriber':
_e('关注者');
break;
case 'visitor':
_e('访问者');
break;
default:
break;
} ?></td>
</tr>
<?php endwhile; ?>
<?php endwhile; ?>
</tbody>
</table><!-- end .typecho-list-table -->
</div><!-- end .typecho-table-wrap -->
</form><!-- end .operate-form -->
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>" href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>"
href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
</div>
</div>
<?php if($users->have()): ?>
</div>
<?php if ($users->have()): ?>
<ul class="typecho-pager">
<?php $users->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
<?php endif; ?>
</form>
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -3,37 +3,35 @@ include 'common.php';
include 'header.php';
include 'menu.php';
$phpMaxFilesize = function_exists('ini_get') ? trim(ini_get('upload_max_filesize')) : 0;
if (preg_match("/^([0-9]+)([a-z]{1,2})$/i", $phpMaxFilesize, $matches)) {
$phpMaxFilesize = strtolower($matches[1] . $matches[2] . (1 == strlen($matches[2]) ? 'b' : ''));
}
Typecho_Widget::widget('Widget_Contents_Attachment_Edit')->to($attachment);
\Widget\Contents\Attachment\Edit::alloc()->prepare()->to($attachment);
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main">
<div class="col-mb-12 col-tb-8" role="main">
<?php if ($attachment->attachment->isImage): ?>
<p><img src="<?php $attachment->attachment->url(); ?>" alt="<?php $attachment->attachment->name(); ?>" class="typecho-attachment-photo" /></p>
<p><img src="<?php $attachment->attachment->url(); ?>"
alt="<?php $attachment->attachment->name(); ?>" class="typecho-attachment-photo"/></p>
<?php endif; ?>
<p>
<?php $mime = Typecho_Common::mimeIconType($attachment->attachment->mime); ?>
<?php $mime = \Typecho\Common::mimeIconType($attachment->attachment->mime); ?>
<i class="mime-<?php echo $mime; ?>"></i>
<a href=""><strong><?php $attachment->attachment->name(); ?></strong></a>
<span><?php echo number_format(ceil($attachment->attachment->size / 1024)); ?> Kb</span>
</p>
<p>
<input id="attachment-url" type="text" class="mono w-100" value="<?php $attachment->attachment->url(); ?>" readonly />
<input id="attachment-url" type="text" class="mono w-100"
value="<?php $attachment->attachment->url(); ?>" readonly/>
</p>
<div id="upload-panel" class="p">
<div class="upload-area" draggable="true"><?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?></div>
<div class="upload-area" data-url="<?php $security->index('/action/upload?do=modify'); ?>">
<?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?>
</div>
<ul id="file-list"></ul>
</div>
</div>
@@ -42,152 +40,40 @@ Typecho_Widget::widget('Widget_Contents_Attachment_Edit')->to($attachment);
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';
include 'common-js.php';
include 'file-upload-js.php';
?>
<script src="<?php $options->adminStaticUrl('js', 'moxie.js?v=' . $suffixVersion); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'plupload.js?v=' . $suffixVersion); ?>"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#attachment-url').click(function () {
$(this).select();
});
$('.operate-delete').click(function () {
var t = $(this), href = t.attr('href');
if (confirm(t.attr('lang'))) {
window.location.href = href;
}
return false;
});
$('.upload-area').bind({
dragenter : function () {
$(this).parent().addClass('drag');
},
dragover : function (e) {
$(this).parent().addClass('drag');
},
drop : function () {
$(this).parent().removeClass('drag');
},
dragend : function () {
$(this).parent().removeClass('drag');
},
dragleave : function () {
$(this).parent().removeClass('drag');
}
});
function fileUploadStart (file) {
$('<ul id="file-list"></ul>').appendTo('#upload-panel');
$('<li id="' + file.id + '" class="loading">'
+ file.name + '</li>').prependTo('#file-list');
}
function fileUploadError (error) {
var file = error.file, code = error.code, word;
switch (code) {
case plupload.FILE_SIZE_ERROR:
word = '<?php _e('文件大小超过限制'); ?>';
break;
case plupload.FILE_EXTENSION_ERROR:
word = '<?php _e('文件扩展名不被支持'); ?>';
break;
case plupload.FILE_DUPLICATE_ERROR:
word = '<?php _e('文件已经上传过'); ?>';
break;
case plupload.HTTP_ERROR:
default:
word = '<?php _e('上传出现错误'); ?>';
break;
}
var fileError = '<?php _e('%s 上传失败'); ?>'.replace('%s', file.name),
li, exist = $('#' + file.id);
if (exist.length > 0) {
li = exist.removeClass('loading').html(fileError);
} else {
$('<ul id="file-list"></ul>').appendTo('#upload-panel');
li = $('<li>' + fileError + '<br />' + word + '</li>').prependTo('#file-list');
}
li.effect('highlight', {color : '#FBC2C4'}, 2000, function () {
$(this).remove();
$(document).ready(function () {
$('#attachment-url').click(function () {
$(this).select();
});
}
function fileUploadComplete (id, url, data) {
var img = $('.typecho-attachment-photo');
$('.operate-delete').click(function () {
var t = $(this), href = t.attr('href');
if (img.length > 0) {
img.get(0).src = '<?php $attachment->attachment->url(); ?>?' + Math.random();
}
$('#' + id).html('<?php _e('文件 %s 已经替换'); ?>'.replace('%s', data.title))
.effect('highlight', 1000, function () {
$(this).remove();
$('#file-list').remove();
});
}
var uploader = new plupload.Uploader({
browse_button : $('.upload-file').get(0),
url : '<?php $security->index('/action/upload?do=modify&cid=' . $attachment->cid); ?>',
runtimes : 'html5,flash,html4',
flash_swf_url : '<?php $options->adminStaticUrl('js', 'Moxie.swf'); ?>',
drop_element : $('.upload-area').get(0),
filters : {
max_file_size : '<?php echo $phpMaxFilesize ?>',
mime_types : [{'title' : '<?php _e('允许上传的文件'); ?>', 'extensions' : '<?php $attachment->attachment->type(); ?>'}],
prevent_duplicates : true
},
multi_selection : false,
init : {
FilesAdded : function (up, files) {
plupload.each(files, function(file) {
fileUploadStart(file);
});
uploader.start();
},
FileUploaded : function (up, file, result) {
if (200 == result.status) {
var data = $.parseJSON(result.response);
if (data) {
fileUploadComplete(file.id, data[0], data[1]);
return;
}
}
fileUploadError({
code : plupload.HTTP_ERROR,
file : file
});
},
Error : function (up, error) {
fileUploadError(error);
if (confirm(t.attr('lang'))) {
window.location.href = href;
}
}
});
uploader.init();
});
return false;
});
Typecho.uploadComplete = function (attachment) {
if (attachment.isImage) {
$('.typecho-attachment-photo').attr('src', attachment.url + '?' + Math.random());
}
$('#file-list li').text('<?php _e('文件 %s 已经替换'); ?>'.replace('%s', attachment.title))
.effect('highlight', 1000, function () {
$(this).remove();
});
};
});
</script>
<?php
include 'footer.php';

View File

@@ -1,15 +1,22 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<div class="typecho-head-nav clearfix" role="navigation">
<nav id="typecho-nav-list">
<?php $menu->output(); ?>
<?php if (!defined('__TYPECHO_ADMIN__')) exit; ?>
<header class="typecho-head-nav" role="navigation">
<nav>
<details class="menu-bar">
<summary><?php _e('菜单'); ?></summary>
</details>
<menu>
<?php $menu->output(); ?>
<li class="operate">
<?php \Typecho\Plugin::factory('admin/menu.php')->call('navBar'); ?><a title="<?php
if ($user->logged > 0) {
$logged = new \Typecho\Date($user->logged);
_e('最后登录: %s', $logged->word());
}
?>" href="<?php $options->adminUrl('profile.php'); ?>" class="author"><?php $user->screenName(); ?></a><a
class="exit" href="<?php $options->logoutUrl(); ?>"><?php _e('登出'); ?></a><a
href="<?php $options->siteUrl(); ?>"><?php _e('网站'); ?></a>
</li>
</menu>
</nav>
<div class="operate">
<?php Typecho_Plugin::factory('admin/menu.php')->navBar(); ?>
<a title="<?php
if ($user->logged > 0) {
_e('最后登录: %s', Typecho_I18n::dateWord($user->logged + $options->timezone, $options->gmtTime + $options->timezone));
}
?>" href="<?php $options->adminUrl('profile.php'); ?>" class="author"><?php $user->screenName(); ?></a><a class="exit" href="<?php $options->logoutUrl(); ?>"><?php _e('登出'); ?></a><a href="<?php $options->siteUrl(); ?>"><?php _e('网站'); ?></a>
</div>
</div>
</header>

View File

@@ -4,16 +4,16 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
<?php Typecho_Widget::widget('Widget_Options_Discussion')->form()->render(); ?>
<?php \Widget\Options\Discussion::alloc()->form()->render(); ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,16 +4,16 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
<?php Typecho_Widget::widget('Widget_Options_General')->form()->render(); ?>
<?php \Widget\Options\General::alloc()->form()->render(); ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,16 +4,16 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
<?php Typecho_Widget::widget('Widget_Options_Permalink')->form()->render(); ?>
<?php \Widget\Options\Permalink::alloc()->form()->render(); ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,16 +4,16 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
<?php Typecho_Widget::widget('Widget_Plugins_Config')->config()->render(); ?>
<?php \Widget\Plugins\Config::alloc()->config()->render(); ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,16 +4,16 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
<?php Typecho_Widget::widget('Widget_Options_Reading')->form()->render(); ?>
<?php \Widget\Options\Reading::alloc()->form()->render(); ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,25 +4,17 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<?php include 'theme-tabs.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12">
<ul class="typecho-option-tabs fix-tabs clearfix">
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a></li>
<?php if (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__): ?>
<li><a href="<?php $options->adminUrl('theme-editor.php'); ?>"><?php _e('编辑当前外观'); ?></a></li>
<?php endif; ?>
<li class="current"><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
</ul>
</div>
<div class="col-mb-12 col-tb-8 col-tb-offset-2" role="form">
<?php Typecho_Widget::widget('Widget_Themes_Config')->config()->render(); ?>
<?php \Widget\Themes\Config::alloc()->config()->render(); ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -1,8 +1,9 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php if (!defined('__TYPECHO_ADMIN__')) exit; ?>
<div class="typecho-page-title">
<h2><?php echo $menu->title; ?><?php
<h2><?php echo $menu->title; ?></h2>
<?php
if (!empty($menu->addLink)) {
echo "<a href=\"{$menu->addLink}\">" . _t("新增") . "</a>";
}
?></h2>
?>
</div>

View File

@@ -3,122 +3,124 @@ include 'common.php';
include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<?php Typecho_Widget::widget('Widget_Plugins_List@activated', 'activated=1')->to($activatedPlugins); ?>
<?php \Widget\Plugins\Rows::allocWithAlias('activated', 'activated=1')->to($activatedPlugins); ?>
<?php if ($activatedPlugins->have() || !empty($activatedPlugins->activatedPlugins)): ?>
<h4 class="typecho-list-table-title"><?php _e('启用的插件'); ?></h4>
<div class="typecho-table-wrap">
<h4 class="typecho-list-table-title"><?php _e('启用的插件'); ?></h4>
<table class="typecho-list-table">
<colgroup>
<col width="25%"/>
<col width="45%"/>
<col width="8%"/>
<col width="10%"/>
<col width="8%" class="kit-hidden-mb"/>
<col width="10%" class="kit-hidden-mb"/>
<col width=""/>
</colgroup>
<thead>
<tr>
<th><?php _e('名称'); ?></th>
<th><?php _e('描述'); ?></th>
<th><?php _e('版本'); ?></th>
<th><?php _e('作者'); ?></th>
<th><?php _e('操作'); ?></th>
</tr>
<tr>
<th><?php _e('名称'); ?></th>
<th><?php _e('描述'); ?></th>
<th class="kit-hidden-mb"><?php _e('版本'); ?></th>
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
<th><?php _e('操作'); ?></th>
</tr>
</thead>
<tbody>
<?php while ($activatedPlugins->next()): ?>
<?php while ($activatedPlugins->next()): ?>
<tr id="plugin-<?php $activatedPlugins->name(); ?>">
<td><?php $activatedPlugins->title(); ?>
<?php if (!$activatedPlugins->dependence): ?>
<img src="<?php $options->adminUrl('images/notice.gif'); ?>" title="<?php _e('%s 无法在此版本的typecho下正常工作', $activatedPlugins->title); ?>" alt="<?php _e('%s 无法在此版本的typecho下正常工作', $activatedPlugins->title); ?>" class="tiny" />
<?php endif; ?>
<?php if (!$activatedPlugins->dependence): ?>
<i class="i-delete"
title="<?php _e('%s 无法在此版本的typecho下正常工作', $activatedPlugins->title); ?>"></i>
<?php endif; ?>
</td>
<td><?php $activatedPlugins->description(); ?></td>
<td><?php $activatedPlugins->version(); ?></td>
<td><?php echo empty($activatedPlugins->homepage) ? $activatedPlugins->author : '<a href="' . $activatedPlugins->homepage
. '">' . $activatedPlugins->author . '</a>'; ?></td>
<td class="kit-hidden-mb"><?php $activatedPlugins->version(); ?></td>
<td class="kit-hidden-mb"><?php echo empty($activatedPlugins->homepage) ? $activatedPlugins->author : '<a href="' . $activatedPlugins->homepage
. '">' . $activatedPlugins->author . '</a>'; ?></td>
<td>
<?php if ($activatedPlugins->activate || $activatedPlugins->deactivate || $activatedPlugins->config || $activatedPlugins->personalConfig): ?>
<?php if ($activatedPlugins->config): ?>
<a href="<?php $options->adminUrl('options-plugin.php?config=' . $activatedPlugins->name); ?>"><?php _e('设置'); ?></a>
&bull;
<?php endif; ?>
<a lang="<?php _e('你确认要禁用插件 %s 吗?', $activatedPlugins->name); ?>" href="<?php $security->index('/action/plugins-edit?deactivate=' . $activatedPlugins->name); ?>"><?php _e('禁用'); ?></a>
<a lang="<?php _e('你确认要禁用插件 %s 吗?', $activatedPlugins->name); ?>"
href="<?php $security->index('/action/plugins-edit?deactivate=' . $activatedPlugins->name); ?>"><?php _e('禁用'); ?></a>
<?php else: ?>
<span class="important"><?php _e('即插即用'); ?></span>
<?php endif; ?>
</td>
</tr>
<?php endwhile; ?>
<?php if (!empty($activatedPlugins->activatedPlugins)): ?>
<?php endwhile; ?>
<?php if (!empty($activatedPlugins->activatedPlugins)): ?>
<?php foreach ($activatedPlugins->activatedPlugins as $key => $val): ?>
<tr>
<td><?php echo $key; ?></td>
<td colspan="3"><span class="warning"><?php _e('此插件文件已经损坏或者被不安全移除, 强烈建议你禁用它'); ?></span></td>
<td><a lang="<?php _e('你确认要禁用插件 %s 吗?', $key); ?>" href="<?php $security->index('/action/plugins-edit?deactivate=' . $key); ?>"><?php _e('禁用'); ?></a></td>
</tr>
<tr>
<td><?php echo $key; ?></td>
<td colspan="3"><span
class="warning"><?php _e('此插件文件已经损坏或者被不安全移除, 强烈建议你禁用'); ?></span></td>
<td><a lang="<?php _e('你确认要禁用插件 %s 吗?', $key); ?>"
href="<?php $security->index('/action/plugins-edit?deactivate=' . $key); ?>"><?php _e('禁用'); ?></a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<?php Typecho_Widget::widget('Widget_Plugins_List@unactivated', 'activated=0')->to($deactivatedPlugins); ?>
<?php \Widget\Plugins\Rows::allocWithAlias('unactivated', 'activated=0')->to($deactivatedPlugins); ?>
<?php if ($deactivatedPlugins->have() || !$activatedPlugins->have()): ?>
<h4 class="typecho-list-table-title"><?php _e('禁用的插件'); ?></h4>
<div class="typecho-table-wrap">
<h4 class="typecho-list-table-title"><?php _e('禁用的插件'); ?></h4>
<table class="typecho-list-table deactivate">
<colgroup>
<col width="25%"/>
<col width="45%"/>
<col width="8%"/>
<col width="10%"/>
<col width="8%" class="kit-hidden-mb"/>
<col width="10%" class="kit-hidden-mb"/>
<col width=""/>
</colgroup>
<thead>
<tr>
<th><?php _e('名称'); ?></th>
<th><?php _e('描述'); ?></th>
<th><?php _e('版本'); ?></th>
<th><?php _e('作者'); ?></th>
<th class="typecho-radius-topright"><?php _e('操作'); ?></th>
</tr>
<tr>
<th><?php _e('名称'); ?></th>
<th><?php _e('描述'); ?></th>
<th class="kit-hidden-mb"><?php _e('版本'); ?></th>
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
<th class="typecho-radius-topright"><?php _e('操作'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($deactivatedPlugins->have()): ?>
<?php if ($deactivatedPlugins->have()): ?>
<?php while ($deactivatedPlugins->next()): ?>
<tr id="plugin-<?php $deactivatedPlugins->name(); ?>">
<td><?php $deactivatedPlugins->title(); ?></td>
<td><?php $deactivatedPlugins->description(); ?></td>
<td><?php $deactivatedPlugins->version(); ?></td>
<td><?php echo empty($deactivatedPlugins->homepage) ? $deactivatedPlugins->author : '<a href="' . $deactivatedPlugins->homepage
. '">' . $deactivatedPlugins->author . '</a>'; ?></td>
<td>
<a href="<?php $security->index('/action/plugins-edit?activate=' . $deactivatedPlugins->name); ?>"><?php _e('启用'); ?></a>
<tr id="plugin-<?php $deactivatedPlugins->name(); ?>">
<td><?php $deactivatedPlugins->title(); ?></td>
<td><?php $deactivatedPlugins->description(); ?></td>
<td class="kit-hidden-mb"><?php $deactivatedPlugins->version(); ?></td>
<td class="kit-hidden-mb"><?php echo empty($deactivatedPlugins->homepage) ? $deactivatedPlugins->author : '<a href="' . $deactivatedPlugins->homepage
. '">' . $deactivatedPlugins->author . '</a>'; ?></td>
<td>
<a href="<?php $security->index('/action/plugins-edit?activate=' . $deactivatedPlugins->name); ?>"><?php _e('启用'); ?></a>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="5"><h6 class="typecho-list-table-title"><?php _e('没有安装插件'); ?></h6>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="5"><h6 class="typecho-list-table-title"><?php _e('没有安装插件'); ?></h6></td>
</tr>
<?php endif; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

27
admin/preview.php Normal file
View File

@@ -0,0 +1,27 @@
<?php
include 'common.php';
/** 获取内容 Widget */
\Widget\Archive::alloc('type=single&checkPermalink=0&preview=1')->to($content);
/** 检测是否存在 */
if (!$content->have()) {
$response->redirect($options->adminUrl);
}
/** 检测权限 */
if (!$user->pass('editor', true) && $content->authorId != $user->uid) {
$response->redirect($options->adminUrl);
}
/** 输出内容 */
$content->render();
?>
<script>
window.onbeforeunload = function () {
if (!!window.parent) {
window.parent.postMessage('cancelPreview', '<?php $options->rootUrl(); ?>');
}
}
</script>

View File

@@ -3,56 +3,60 @@ include 'common.php';
include 'header.php';
include 'menu.php';
$stat = Typecho_Widget::widget('Widget_Stat');
$stat = \Widget\Stat::alloc();
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main">
<div class="col-mb-12 col-tb-3">
<p><a href="http://gravatar.com/emails/" title="<?php _e('在 Gravatar 上修改头像'); ?>"><?php echo '<img class="profile-avatar" src="' . Typecho_Common::gravatarUrl($user->mail, 220, 'X', 'mm', $request->isSecure()) . '" alt="' . $user->screenName . '" />'; ?></a></p>
<p><a href="https://gravatar.com/"
title="<?php _e('在 Gravatar 上修改头像'); ?>"><?php echo '<img class="profile-avatar" src="' . \Typecho\Common::gravatarUrl($user->mail, 220, 'X', 'mm', $request->isSecure()) . '" alt="' . $user->screenName . '" />'; ?></a>
</p>
<h2><?php $user->screenName(); ?></h2>
<p><?php $user->name(); ?></p>
<p><?php _e('目前有 <em>%s</em> 篇日志, 并有 <em>%s</em> 条关于你的评论在 <em>%s</em> 个分类中.',
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?></p>
<p><?php _e('目前有 <em>%s</em> 篇日志, 并有 <em>%s</em> 条关于你的评论在 <em>%s</em> 个分类中.',
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?></p>
<p><?php
if ($user->logged > 0) {
_e('最后登录: %s', Typecho_I18n::dateWord($user->logged + $options->timezone, $options->gmtTime + $options->timezone));
}
?></p>
if ($user->logged > 0) {
$logged = new \Typecho\Date($user->logged);
_e('最后登录: %s', $logged->word());
}
?></p>
</div>
<div class="col-mb-12 col-tb-6 col-tb-offset-1 typecho-content-panel" role="form">
<section>
<h3><?php _e('个人资料'); ?></h3>
<?php Typecho_Widget::widget('Widget_Users_Profile')->profileForm()->render(); ?>
<?php \Widget\Users\Profile::alloc()->profileForm()->render(); ?>
</section>
<?php if($user->pass('contributor', true)): ?>
<br>
<section id="writing-option">
<h3><?php _e('撰写设置'); ?></h3>
<?php Typecho_Widget::widget('Widget_Users_Profile')->optionsForm()->render(); ?>
</section>
<?php if ($user->pass('contributor', true)): ?>
<br>
<section id="writing-option">
<h3><?php _e('撰写设置'); ?></h3>
<?php \Widget\Users\Profile::alloc()->optionsForm()->render(); ?>
</section>
<?php endif; ?>
<br>
<section id="change-password">
<h3><?php _e('密码修改'); ?></h3>
<?php Typecho_Widget::widget('Widget_Users_Profile')->personalFormList(); ?>
<?php Typecho_Widget::widget('Widget_Users_Profile')->passwordForm()->render(); ?>
<?php \Widget\Users\Profile::alloc()->passwordForm()->render(); ?>
</section>
<?php \Widget\Users\Profile::alloc()->personalFormList(); ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';
include 'common-js.php';
include 'form-js.php';
Typecho_Plugin::factory('admin/profile.php')->bottom();
\Typecho\Plugin::factory('admin/profile.php')->call('bottom');
include 'footer.php';
?>

View File

@@ -4,10 +4,10 @@ include 'common.php';
if ($user->hasLogin() || !$options->allowRegister) {
$response->redirect($options->siteUrl);
}
$rememberName = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_name'));
$rememberMail = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_mail'));
Typecho_Cookie::delete('__typecho_remember_name');
Typecho_Cookie::delete('__typecho_remember_mail');
$rememberName = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_name', ''));
$rememberMail = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_mail', ''));
\Typecho\Cookie::delete('__typecho_remember_name');
\Typecho\Cookie::delete('__typecho_remember_mail');
$bodyClass = 'body-100';
@@ -15,7 +15,7 @@ include 'header.php';
?>
<div class="typecho-login-wrap">
<div class="typecho-login">
<h1><a href="http://typecho.org" class="i-logo">Typecho</a></h1>
<h1><a href="https://typecho.org" class="i-logo">Typecho</a></h1>
<form action="<?php $options->registerAction(); ?>" method="post" name="register" role="form">
<p>
<label for="name" class="sr-only"><?php _e('用户名'); ?></label>

View File

@@ -1,109 +0,0 @@
/**
* 后台头部导航
*/
.typecho-head-nav {
padding: 0 10px;
background: #292D33;
}
.typecho-head-nav a {
color: #BBB;
}
.typecho-head-nav a:hover,
.typecho-head-nav a:focus {
color: #FFF;
text-decoration: none;
}
#typecho-nav-list {
float: left;
ul {
list-style: none;
margin: 0;
padding: 0;
}
}
#typecho-nav-list ul:first-child {
border-left: 1px solid #383D45;
}
#typecho-nav-list .root {
position: relative;
float: left;
}
#typecho-nav-list .parent a {
display: block;
float: left;
padding: 0 20px;
border-right: 1px solid #383D45;
height: 36px;
line-height: 36px;
color: #BBB;
}
#typecho-nav-list .parent a:hover,
#typecho-nav-list .focus .parent a,
#typecho-nav-list .root:hover .parent a {
background: #202328;
color: #FFF;
text-decoration: none;
}
#typecho-nav-list .focus .parent a {
font-weight: bold;
}
#typecho-nav-list .child {
position: absolute;
top: 36px;
display: none;
margin: 0;
min-width: 160px;
max-width: 240px;
background: #202328;
z-index: 250;
}
#typecho-nav-list .root:hover .child {
display: block;
}
#typecho-nav-list .child li a {
color: #BBB;
display: block;
padding: 0 20px;
overflow: hidden;
text-overflow : ellipsis;
white-space: nowrap;
height: 36px;
line-height: 36px;
}
#typecho-nav-list .child li a:hover,
#typecho-nav-list .child li a:focus {
background: #292D33;
color: #FFF;
}
#typecho-nav-list .child li.focus a {
color: #6DA1BB;
font-weight: bold;
}
.typecho-head-nav .operate {
float: right;
}
.typecho-head-nav .operate a {
display: inline-block;
margin-left: -1px;
padding: 0 20px;
border: 1px solid #383D45;
border-width: 0 1px;
line-height: 36px;
color: #BBB;
}
.typecho-head-nav .operate a:hover {
background-color: #202328;
color: #FFF;
}

View File

@@ -1,36 +0,0 @@
/**
* 后台分页
*/
.typecho-pager {
list-style: none;
float: right;
margin: 0;
padding: 0;
line-height: 1;
text-align: center;
zoom: 1;
}
.typecho-pager li {
display: inline-block;
margin: 0 3px;
height: 28px;
line-height: 28px;
}
.typecho-pager a {
display: block;
padding: 0 10px;
@include border-radius(2px);
}
.typecho-pager a:hover {
text-decoration: none;
background: #E9E9E6;
}
.typecho-pager li.current a {
background: #E9E9E6;
color: #444;
}

View File

@@ -1,248 +0,0 @@
/*
* Editor
*/
.editor {
margin-bottom: -0.5em;
}
.wmd-button-row {
list-style: none;
margin: 0;
padding: 0;
height: 26px;
line-height: 1;
li {
display: inline-block;
margin-right: 4px;
padding: 3px;
cursor: pointer;
vertical-align: middle;
@include border-radius(2px);
&:hover {
background-color: #E9E9E6;
}
&.wmd-spacer {
height: 20px;
margin: 0 10px 0 6px;
padding: 0;
width: 1px;
background: #E9E9E6;
cursor: default;
}
}
}
#wmd-button-row span {
display: block;
width: 20px;
height: 20px;
background: transparent url(../img/editor.png) no-repeat;
}
@media
(-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
#wmd-button-row span {
background-image: url(../img/editor@2x.png);
@include background-size(320px auto);
}
}
// 撰写预览切换 tab
.wmd-edittab {
float: right;
margin-top: 3px;
font-size: .92857em;
a {
display: inline-block;
padding: 0 8px;
margin-left: 5px;
height: 20px;
line-height: 20px;
&:hover {
text-decoration: none;
}
&.active {
background: #E9E9E6;
color: #999;
}
}
}
// 控制被隐藏的 tab全屏时显示
.wmd-hidetab {
display: none;
}
// 隐藏编辑器,但占位
.wmd-visualhide {
visibility: hidden;
}
/* 对话框 */
.wmd-prompt-background {
background-color: #000;
}
.wmd-prompt-dialog {
position: fixed;
z-index: 1001;
top: 50%;
left: 50%;
margin-top: -95px;
margin-left: -200px;
padding: 20px;
width: 360px;
background: #F6F6F3;
p { margin: 0 0 5px; }
form { margin-top: 10px; }
input[type="text"] {
margin-bottom: 10px;
width: 100%;
}
button { margin-right: 10px; }
}
/* 预览 */
#wmd-preview {
background: #FFF;
margin: 1em 0;
padding: 0 15px;
word-wrap: break-word;
overflow: auto;
@include border-radius(2px);
img { max-width: 100%; }
code, pre {
padding: 2px 4px;
background: #F3F3F0;
font-size: .92857em;
}
code { color: #C13; }
pre {
padding: 1em;
code {
padding: 0;
color: #444;
}
}
blockquote {
margin: 1em 1.5em;
padding-left: 1.5em;
border-left: 4px solid #E9E9E6;
color: #777;
}
hr {
margin: 2em auto;
width: 100px;
border: 1px solid #E9E9E6;
border-width: 2px 0 0 0;
}
.summary:after {
display: block;
margin: 2em 0;
background: #FFF9E8;
color: darken(#FFF9E8, 55%);
font-size: .85714em;
text-align: center;
content: "- more -";
}
}
/* 上传面板动画效果 */
@keyframes fullscreen-upload {
0% { right: -280px; }
100% { right: -1px; }
}
@-moz-keyframes fullscreen-upload {
0% { right: -280px; }
100% { right: -1px; }
}
@-webkit-keyframes fullscreen-upload {
0% { right: -280px; }
100% { right: -1px; }
}
@-o-keyframes fullscreen-upload {
0% { right: -280px; }
100% { right: -1px; }
}
/* 编辑器全屏 */
.fullscreen {
#wmd-button-bar, #text, #wmd-preview, .submit {
// position: fixed;
position: absolute;
top: 0;
width: 50%;
background: #FFF;
z-index: 999;
@include box-sizing(border-box);
@include border-radius(0);
}
#wmd-button-bar {
left: 0;
padding: 13px 20px;
border-bottom: 1px solid #F3F3F0;
z-index: 1000;
}
#text {
top: 53px;
left: 0;
padding: 20px;
border: none;
outline: none;
}
#wmd-preview {
top: 53px;
right: 0;
margin: 0;
padding: 5px 20px;
border: none;
border-left: 1px solid #F3F3F0;
background: #F6F6F3;
overflow: auto;
code, pre {
background: #F0F0EC;
}
}
.submit {
right: 0;
margin: 0;
padding: 10px 20px;
border-bottom: 1px solid #F3F3F0;
}
#upload-panel {
-webkit-box-shadow: 0 4px 16px rgba(0,0,0,0.225);
box-shadow: 0 4px 16px rgba(0,0,0,0.225);
border-style: solid;
}
// 全屏附件上传
#tab-files {
position: absolute;
top: 52px;
right: -1px;
width: 280px;
z-index: 1001;
animation: fullscreen-upload 0.5s;
-moz-animation: fullscreen-upload 0.5s;
-webkit-animation: fullscreen-upload 0.5s;
-o-animation: fullscreen-upload 0.5s;
}
.wmd-edittab,
.typecho-post-option,
.title,
.url-slug,
.typecho-page-title,
.typecho-head-nav,
.message { display: none; }
.wmd-hidetab { display: block; }
.wmd-visualhide,
#btn-fullscreen-upload {
visibility: visible;
}
}

View File

@@ -1,12 +0,0 @@
@import "compass/css3/background-size";
@mixin image-2x($image, $width, $height) {
@media (-webkit-min-device-pixel-ratio: 1.3),
(min-resolution: 124.8dpi),
(min-resolution: 1.3dppx) {
& {
background-image: url($image);
@include background-size($width $height);
}
}
}

View File

@@ -1,947 +0,0 @@
/* vim: set et sw=2 ts=2 sts=2 fdm=marker ff=unix fenc=utf8 */
/**
* Typecho 后台样式
*
* @author Typecho Team
* @since 2008-09-26
* @update 2013-11-02
* @link http://www.typecho.org/
* @version 0.9
*/
@import "compass";
/**
* Typecho 全局样式
*/
html {
height: 100%;
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
background: #F6F6F3;
color: #444;
font-size: 87.5%;
line-height: 1.5;
}
a {
color: #467B96;
text-decoration: none;
&:hover {
color: #499BC3;
text-decoration: underline;
}
}
code, pre, .mono {
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
}
.p { margin: 1em 0; }
.body-100 {
height: 100%;
}
a.balloon-button {
display: inline-block;
padding: 0 6px;
min-width: 12px;
height: 18px;
line-height: 18px;
background: #D8E7EE;
font-size: .85714em;
text-align: center;
text-decoration: none;
/** 修正ie中文不对齐 */
zoom:1;
-moz-border-radius: 30px;
-webkit-border-radius: 30px;
border-radius: 30px;
}
a.button:hover, a.balloon-button:hover {
background-color: #A5CADC;
color: #FFF;
text-decoration: none;
}
@import "forms";
@import "buttons";
@import "messages";
@import "pagenavi";
@import "header";
@import "footer";
/* 低版本浏览器升级提示 */
.browsehappy {
border: none;
text-align: center;
}
/** 顶部消息样式 by 70 */
.popup {
display: none;
position: absolute;
top: 0;
left: 0;
margin: 0;
padding: 8px 0;
border: none;
width: 100%;
z-index: 10;
text-align: center;
-moz-border-radius: 0;
-webkit-border-radius: 0;
border-radius: 0;
}
.popup ul {
list-style: none;
margin: 0;
padding: 0;
text-align: center;
}
.popup ul li {
display: inline-block;
margin-right: 10px;
}
/**
* logo 的样式
*/
.logo {
}
/**
* 载入状态
*/
.loading {
padding-left: 20px !important;
background: transparent url(../img/ajax-loader.gif) no-repeat left center;
}
/**
* 典型配置选项
*/
.typecho-option {
list-style: none;
margin: 1em 0;
padding: 0;
}
.typecho-option li {
}
.typecho-option-submit li {
border-bottom: none;
}
.typecho-option label.typecho-label {
display: block;
margin-bottom: .5em;
font-weight: bold;
}
.typecho-option label.required:after {
content: " *";
color: #B94A48;
}
.typecho-option label.typecho-label+input {
}
.typecho-option span { margin-right: 15px; }
.typecho-option .description {
margin: .5em 0 0;
color: #999;
font-size: .92857em;
}
.front-archive {
padding-left: 1.5em;
}
.profile-avatar {
border: 1px dashed #D9D9D6;
max-width: 100%;
}
/** 增加配置面板内部的错误样式 by 70 */
/**
* 安装样式
*
* @author mingcheng
* @date 2008-09-06
*/
/**
* 安装向导
*/
.typecho-install {
padding-bottom: 2em;
}
.typecho-install-patch {
margin-bottom: 2em;
padding: 2em 0;
background-color: #292D33;
color: #FFF;
text-align: center;
}
.typecho-install-patch ol {
list-style: none;
margin: 3em 0 1em;
padding: 0;
color: #999;
}
.typecho-install-patch li {
display: inline-block;
margin: 0 .8em;
}
.typecho-install-patch span {
display: inline-block;
margin-right: 5px;
width: 20px;
height: 20px;
line-height: 20px;
border: 2px solid #999;
text-align: center;
border-radius: 2em;
}
.typecho-install-patch li.current {
color: #FFF;
font-weight: bold;
}
.typecho-install-patch li.current span {
border-color: #FFF;
}
/**
* 安装主体内容
*/
.typecho-install .typecho-install-body input {
width: 100%;
}
.typecho-install-body .typecho-option li {
margin: 1em 0;
}
/**
* 欢迎界面
*/
#typecho-welcome {
margin: 1em 0;
padding: 1em 2em;
background-color: #E9E9E6;
}
.welcome-board {
color: #999;
font-size: 1.15em;
em {
color: #444;
font-size: 2em;
font-style: normal;
font-family: Georgia, serif;
}
}
#start-link {
margin-bottom: 25px;
padding: 0 0 35px;
border-bottom: 1px solid #ECECEC;
li {
float: left;
margin-right: 1.5em;
}
.balloon {
margin-top: 2px;
}
}
.latest-link {
li {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
span {
display: inline-block;
margin-right: 4px;
padding-right: 8px;
border-right: 1px solid #ECECEC;
width: 37px;
text-align: right;
color: #999;
}
}
.update-check {
font-size: 14px;
}
/**
* 登录框
*/
.typecho-login-wrap {
display: table;
margin: 0 auto;
height: 100%;
}
.typecho-login {
display: table-cell;
padding: 30px 0 100px;
width: 280px;
text-align: center;
vertical-align: middle;
h1 {
margin: 0 0 1em;
}
}
.typecho-login .more-link {
margin-top: 2em;
color: #CCC;
}
.typecho-login .more-link a { margin: 0 3px; }
/**
* 标题
*/
.typecho-page-title {
}
.typecho-page-title h2 {
margin: 25px 0 10px;
font-size: 1.28571em;
}
.typecho-page-title h2 a {
margin-left: 10px;
padding: 3px 8px;
background: #E9E9E6;
font-size: .8em;
border-radius: 2px;
}
.typecho-page-title h2 a:hover {
text-decoration: none;
}
/**
* 后台页面主体
*/
/**
* 主页主体
*/
.typecho-dashboard {
}
.typecho-dashboard ul {
list-style: none;
padding: 0;
}
.typecho-dashboard li {
margin-bottom: 5px;
}
/**
* 标签页
*/
.typecho-option-tabs {
list-style: none;
margin: 1em 0 0;
padding: 0;
font-size: 13px;
text-align: center;
&.fix-tabs {
margin-bottom: 1em;
}
}
.typecho-option-tabs a {
display: block;
margin-right: -1px;
border: 1px solid #D9D9D6;
padding: 0 15px;
height: 26px;
line-height: 26px;
color: #666;
@include box-sizing(border-box);
}
.typecho-option-tabs a:hover {
background-color: #E9E9E6;
color: #666;
text-decoration: none;
}
.typecho-option-tabs li {
float: left;
&:first-child a {
@include border-radius(2px 0 0 2px);
}
&:last-child a {
@include border-radius(0 2px 2px 0);
}
}
.typecho-option-tabs.right {
float: right;
}
.typecho-option-tabs li.current a,
.typecho-option-tabs li.active a {
background-color: #E9E9E6;
}
/**
* 表格列表页
*/
/**
* 列表页选项
*/
.typecho-list .typecho-pager {
}
.typecho-list-operate {
margin: 1em 0;
}
.typecho-list-operate input,
.typecho-list-operate button,
.typecho-list-operate select {
vertical-align: bottom;
}
.typecho-list-operate input[type="checkbox"] {
vertical-align: text-top;
}
.typecho-list-operate .operate {
float: left;
}
.typecho-list-operate .search {
float: right;
}
.typecho-list-operate span.operate-delete, a.operate-delete,
.typecho-list-operate span.operate-button-delete, a.operate-button-delete {
color: #B94A48;
}
a.operate-edit {
color: #007700;
}
a.operate-reply {
color: #545c30;
}
.typecho-list-operate a:hover {
text-decoration: none;
}
/**
* 列表表格
*/
/** 增加表格标题 by 70 */
.typecho-list-table-title {
margin: 1em 0;
color: #999;
text-align: center;
}
.typecho-table-wrap {
padding: 30px;
background: #FFF;
}
.typecho-list-table {
width: 100%;
}
.typecho-list-table.deactivate {
color: #999;
}
.typecho-list-table .right {
text-align: right;
}
.typecho-list-table th {
padding: 0 10px 10px;
border-bottom: 2px solid #F0F0EC;
text-align: left;
}
.typecho-list-table td {
padding: 10px;
border-top: 1px solid #F0F0EC;
word-break: break-all;
}
.typecho-list-table .status {
margin-left: 5px;
color: #999;
font-size: .92857em;
font-style: normal;
}
.typecho-list-table tbody tr:hover td {
background-color: #F6F6F3;
}
.typecho-list-table tbody tr.checked td {
background-color: #FFF9E8;
}
.warning {
color: #B94A48;
}
.typecho-list-table tr td .hidden-by-mouse {
@include opacity(0);
}
.typecho-list-table tr:hover td .hidden-by-mouse {
@include opacity(1);
}
/**
* 评论管理
*/
.comment-reply-content {
position: relative;
margin: 1em 0;
padding: 0 1em;
border: 1px solid transparent;
background-color: #F0F0EC;
}
.comment-reply-content:after {
position: absolute;
right: 1em;
border: 8px solid #F0F0EC;
border-color: #F0F0EC #F0F0EC transparent transparent;
content: " ";
}
.comment-meta span,
.comment-date {
font-size: .92857em;
color: #999;
}
.comment-action a, .comment-action span { margin-right: 4px; }
.comment-edit label {
display: block;
}
/**
* 评论回复
*/
#typecho-respond {
padding: 10px;
display: none;
}
/**
* 模板列表
*/
.typecho-theme-list {
}
.typecho-theme-list .theme-item {
}
.typecho-theme-list td {
}
.typecho-theme-list img {
margin: 1em 0;
max-width: 100%;
max-height: 240px;
}
.typecho-theme-list cite {
font-style: normal;
color: #999;
}
.typecho-theme-list tbody tr.current td {
background-color: #FFF9E8;
}
/**
* 后台配置项
*/
.typecho-page-main .typecho-option input.text {
width: 100%;
}
.typecho-page-main .typecho-option input.num {
width: 40px;
}
.typecho-page-main .typecho-option textarea {
width: 100%;
height: 100px;
}
.typecho-page-main .typecho-option .multiline {
display: block;
margin: .3em 0;
&.hidden {
display: none;
}
}
/**
* 编辑模板
*/
.typecho-select-theme {
height: 25px;
line-height: 25px;
margin: 15px 0px;
}
.typecho-select-theme h5 {
color: #E47E00;
font-weight: bold;
float: left;
font-size: 14px;
width: 120px;
margin-right: 10px;
}
.typecho-select-theme select {
width: 150px;
}
/**
* 编辑模板(编辑详情)
*/
.typecho-edit-theme ul {
list-style: none;
margin: 0;
padding: 0;
}
.typecho-edit-theme li {
padding: 3px 10px;
}
.typecho-edit-theme .current {
background-color: #E6E6E3;
}
.typecho-edit-theme .current a {
color: #444;
}
.typecho-edit-theme textarea {
font-size: .92857em;
line-height: 1.2;
height: 500px;
}
/**
* 编写页面
*/
.typecho-post-area .edit-draft-notice {
color: #999;
font-size: .92857em;
}
.typecho-post-area .edit-draft-notice a { color: #B94A48; }
.typecho-post-area .typecho-label {
display: block;
margin: 1em 0 -0.5em;
font-weight: bold;
}
.typecho-post-area #auto-save-message {
display: block;
margin-top: 0.5em;
color: #999;
font-size: .92857em;
}
.typecho-post-area .submit .right button {
margin-left: 5px;
}
.typecho-post-area .right {
float: right;
padding-left: 24px;
}
.typecho-post-area .left {
float: left;
}
.typecho-post-area input.text {
}
.typecho-post-area .out-date {
border: 1px solid #D3DBB3;
padding: 3px;
background: #fff;
}
.typecho-post-area input.title {
font-size: 1.17em;
font-weight: bold;
}
.typecho-post-area .url-slug {
margin-top: -0.5em;
color: #AAA;
font-size: .92857em;
word-break: break-word;
}
.typecho-post-area #slug {
padding: 2px;
border: none;
background: #FFFBCC;
color: #666;
}
.typecho-post-area #text {
resize: none;
}
#advance-panel {
display: none;
}
#custom-field {
margin: 1em 0;
padding: 10px 15px;
background: #FFF;
&.fold {
table, .description { display: none; }
}
.description {
margin-top: 10px;
text-align: right;
button {
float: left;
}
}
p.description {
text-align: left;
}
.typecho-label {
margin: 0;
a {
display: block;
color: #444;
&:hover {
color: #467B96;
text-decoration: none;
}
}
}
table {
margin-top: 10px;
}
td {
padding: 10px 5px;
font-size: .92857em;
border-bottom: 1px solid #F0F0EC;
vertical-align: top;
label {
font-size: 1em;
font-weight: normal;
}
}
select { height: 27px; }
}
.typecho-post-area .is-draft {
background: #FFF1A8;
}
.typecho-post-option .description {
margin-top: -0.5em;
color: #999;
font-size: .92857em;
}
.category-option ul {
list-style: none;
border: 1px solid #D9D9D6;
padding: 6px 12px;
max-height: 240px;
overflow: auto;
background-color: #FFF;
border-radius: 2px;
}
.category-option li {
margin: 3px 0;
}
.visibility-option ul,
.allow-option ul {
list-style: none;
padding: 0;
}
/**
* 标签列表
*/
.typecho-page-main ul.tag-list {
list-style: none;
margin: 0;
padding: 20px;
background-color: #FFF;
}
.typecho-page-main ul.tag-list li {
display: inline-block;
margin: 0 0 5px 0;
padding: 5px 5px 5px 10px;
cursor: pointer;
}
.typecho-page-main ul.tag-list li:hover {
background-color: #E9E9E6;
}
.typecho-page-main ul.tag-list li input {
display: none;
}
.typecho-page-main ul.tag-list li.checked {
background-color: #FFFBCC;
}
.typecho-page-main ul.tag-list li.size-5 { font-size: 1em; }
.typecho-page-main ul.tag-list li.size-10 { font-size: 1.2em; }
.typecho-page-main ul.tag-list li.size-20 { font-size: 1.4em; }
.typecho-page-main ul.tag-list li.size-30 { font-size: 1.6em; }
.typecho-page-main ul.tag-list li.size-0 { font-size: 1.8em; }
.typecho-page-main .tag-edit-link { visibility: hidden; }
.typecho-page-main li:hover .tag-edit-link { visibility: visible; }
.typecho-attachment-photo {
border: 1px solid #E6E6E3;
max-width: 100%;
}
/*
* Upload
*/
#upload-panel {
border: 1px dashed #D9D9D6;
background-color: #FFF;
color: #999;
font-size: .92857em;
&.drag {
background-color: #FFFBCC;
}
}
.upload-area {
padding: 15px;
text-align: center;
}
#file-list {
list-style: none;
margin: 0 10px;
padding: 0;
max-height: 450px;
overflow: auto;
word-break: break-all;
li,
.insert {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
li {
padding: 8px 0;
border-top: 1px dashed #D9D9D6;
}
.insert {
display: block;
max-width: 100%;
}
.file {
margin-left: 5px;
}
.info {
text-transform: uppercase;
}
}
#btn-fullscreen-upload {
visibility: hidden;
}
/**
* 附件管理
*/
.edit-media button { margin-right: 6px; }
/* 拖动调整 textarea 大小 */
.resize {
display: block;
margin: 2px auto 0;
padding: 2px 0;
border: 1px solid #D9D9D6;
border-width: 1px 0;
width: 60px;
cursor: row-resize;
i {
display: block;
height: 1px;
background-color: #D9D9D6;
}
}
/* 拖动排序 */
.tDnD_whileDrag {
background-color: #FFFBCC;
}
/**
* 导入扩展样式
*/
@import "icons";
@import "components";
@import "hidden";

View File

Before

Width:  |  Height:  |  Size: 408 B

After

Width:  |  Height:  |  Size: 408 B

View File

Before

Width:  |  Height:  |  Size: 697 B

After

Width:  |  Height:  |  Size: 697 B

View File

Before

Width:  |  Height:  |  Size: 280 B

After

Width:  |  Height:  |  Size: 280 B

View File

Before

Width:  |  Height:  |  Size: 298 B

After

Width:  |  Height:  |  Size: 298 B

View File

Before

Width:  |  Height:  |  Size: 122 B

After

Width:  |  Height:  |  Size: 122 B

View File

Before

Width:  |  Height:  |  Size: 132 B

After

Width:  |  Height:  |  Size: 132 B

View File

Before

Width:  |  Height:  |  Size: 124 B

After

Width:  |  Height:  |  Size: 124 B

View File

Before

Width:  |  Height:  |  Size: 131 B

After

Width:  |  Height:  |  Size: 131 B

View File

Before

Width:  |  Height:  |  Size: 121 B

After

Width:  |  Height:  |  Size: 121 B

View File

Before

Width:  |  Height:  |  Size: 133 B

After

Width:  |  Height:  |  Size: 133 B

View File

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 118 B

View File

Before

Width:  |  Height:  |  Size: 127 B

After

Width:  |  Height:  |  Size: 127 B

View File

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 219 B

View File

Before

Width:  |  Height:  |  Size: 329 B

After

Width:  |  Height:  |  Size: 329 B

View File

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 287 B

View File

Before

Width:  |  Height:  |  Size: 488 B

After

Width:  |  Height:  |  Size: 488 B

Some files were not shown because too many files have changed in this diff Show More