Merge pull request #7 from typecho/master

同步最新
This commit is contained in:
ShingChi
2013-12-11 18:22:38 -08:00
310 changed files with 3783 additions and 33817 deletions
+13
View File
@@ -75,6 +75,19 @@
}
})();
// 导航菜单 tab 聚焦时展开下拉菜单
(function () {
$('#typecho-nav-list').find('.parent a').focus(function() {
$('#typecho-nav-list').find('.child').hide();
$(this).parents('.root').find('.child').show();
});
$('#typecho-nav-list').find('.child li:last-child a').blur(function() {
$(this).parents('.child').hide();
});
})();
if ($('.typecho-login').length == 0) {
$('a').each(function () {
var t = $(this), href = t.attr('href');
+3 -2
View File
@@ -1,12 +1,13 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<div class="typecho-foot" role="contentinfo">
<div class="copyright">
<?php _e('由 <a href="http://typecho.org">%s</a> 强力驱动, 版本 %s (%s)', $options->software, $prefixVersion, $suffixVersion); ?>
<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>
</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://github.com/typecho/typecho-replica/issues"><?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>
</nav>
</div>
+134 -48
View File
@@ -25,7 +25,7 @@ a {
color: #467B96;
text-decoration: none; }
a:hover {
color: #6DA1BB;
color: #499BC3;
text-decoration: underline; }
code, pre, .mono {
@@ -34,6 +34,9 @@ code, pre, .mono {
.p {
margin: 1em 0; }
.body-100 {
height: 100%; }
a.balloon-button {
display: inline-block;
padding: 0 6px;
@@ -127,10 +130,6 @@ button {
-ms-border-radius: 2px;
-o-border-radius: 2px;
border-radius: 2px;
-webkit-transition-duration: 0.4s;
-moz-transition-duration: 0.4s;
-o-transition-duration: 0.4s;
transition-duration: 0.4s;
display: inline-block;
padding: 0 12px;
height: 32px;
@@ -138,9 +137,13 @@ button {
vertical-align: middle;
zoom: 1; }
button:hover {
-webkit-transition-duration: 0.4s;
-moz-transition-duration: 0.4s;
-o-transition-duration: 0.4s;
transition-duration: 0.4s;
background-color: #dbdbd6; }
button:active, button.active {
background-color: #dbdbd6; }
background-color: #d6d6d0; }
button:disabled {
background-color: #f7f7f6;
cursor: default; }
@@ -168,15 +171,15 @@ button {
-ms-border-radius: 2px;
-o-border-radius: 2px;
border-radius: 2px;
-webkit-transition-duration: 0.4s;
-moz-transition-duration: 0.4s;
-o-transition-duration: 0.4s;
transition-duration: 0.4s;
color: #FFF; }
.primary:hover {
-webkit-transition-duration: 0.4s;
-moz-transition-duration: 0.4s;
-o-transition-duration: 0.4s;
transition-duration: 0.4s;
background-color: #3c6a81; }
.primary:active, .primary.active {
background-color: #3c6a81; }
background-color: #39647a; }
.primary:disabled {
background-color: #508cab;
cursor: default; }
@@ -193,15 +196,15 @@ button {
-ms-border-radius: 2px;
-o-border-radius: 2px;
border-radius: 2px;
-webkit-transition-duration: 0.4s;
-moz-transition-duration: 0.4s;
-o-transition-duration: 0.4s;
transition-duration: 0.4s;
color: #FFF; }
.btn-warn:hover {
-webkit-transition-duration: 0.4s;
-moz-transition-duration: 0.4s;
-o-transition-duration: 0.4s;
transition-duration: 0.4s;
background-color: #a4403f; }
.btn-warn:active, .btn-warn.active {
background-color: #a4403f; }
background-color: #9c3e3c; }
.btn-warn:disabled {
background-color: #c1605e;
cursor: default; }
@@ -261,10 +264,10 @@ button {
.notice {
background: #FFF6BF;
color: #514721; }
color: #8A6D3B; }
.notice a {
color: #514721; }
color: #8A6D3B; }
.success {
background: #E6EFC2;
@@ -295,9 +298,9 @@ button {
*/
.typecho-pager {
list-style: none;
margin: 30px 0 0;
float: right;
margin: 0;
padding: 0;
font-size: 1.14286em;
line-height: 1;
text-align: center;
zoom: 1; }
@@ -305,12 +308,17 @@ button {
.typecho-pager li {
display: inline-block;
margin: 0 3px;
height: 32px;
line-height: 32px; }
height: 28px;
line-height: 28px; }
.typecho-pager a {
display: block;
padding: 0 15px; }
padding: 0 10px;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
-ms-border-radius: 2px;
-o-border-radius: 2px;
border-radius: 2px; }
.typecho-pager a:hover {
text-decoration: none;
@@ -330,7 +338,8 @@ button {
.typecho-head-nav a {
color: #BBB; }
.typecho-head-nav a:hover {
.typecho-head-nav a:hover,
.typecho-head-nav a:focus {
color: #FFF;
text-decoration: none; }
@@ -369,17 +378,16 @@ button {
#typecho-nav-list .child {
position: absolute;
left: -9999em;
top: 36px;
display: none;
margin: 0;
min-width: 160px;
max-width: 240px;
background: #202328;
overflow: hidden;
z-index: 250; }
#typecho-nav-list .root:hover .child {
top: 36px;
left: 0; }
display: block; }
#typecho-nav-list .child li a {
color: #BBB;
@@ -391,7 +399,8 @@ button {
height: 36px;
line-height: 36px; }
#typecho-nav-list .child li a:hover {
#typecho-nav-list .child li a:hover,
#typecho-nav-list .child li a:focus {
background: #292D33;
color: #FFF; }
@@ -419,17 +428,17 @@ button {
* 注脚
*/
.typecho-foot {
padding: 4em 0;
padding: 4em 0 3em;
color: #999;
line-height: 1.8;
text-align: center; }
.typecho-foot .resource {
color: #CCC; }
.typecho-foot .resource a {
margin: 0 3px;
color: #999; }
.typecho-foot .copyright p {
margin: 10px 0 0; }
.typecho-foot .resource {
color: #CCC; }
.typecho-foot .resource a {
margin: 0 3px;
color: #999; }
/* 低版本浏览器升级提示 */
.browsehappy {
@@ -503,6 +512,10 @@ button {
.front-archive {
padding-left: 1.5em; }
.profile-avatar {
border: 1px dashed #D9D9D6;
max-width: 100%; }
/** 增加配置面板内部的错误样式 by 70 */
/**
* 安装样式
@@ -564,14 +577,57 @@ button {
padding: 1em 2em;
background-color: #E9E9E6; }
.welcome-board {
color: #999;
font-size: 1.15em; }
.welcome-board 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; }
#start-link li {
float: left;
margin-right: 1.5em; }
#start-link .balloon {
margin-top: 2px; }
.latest-link li {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; }
.latest-link 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 {
margin: 150px auto 0;
display: table-cell;
padding-bottom: 100px;
width: 280px;
height: 100%;
text-align: center; }
text-align: center;
vertical-align: middle; }
.typecho-login h1 {
margin: 0 0 1em; }
.typecho-login .more-link {
margin-top: 2em;
@@ -934,10 +990,13 @@ a.operate-reply {
#custom-field .description button {
float: left; }
#custom-field .typecho-label {
margin: 0;
cursor: pointer; }
#custom-field .typecho-label:hover {
color: #467B96; }
margin: 0; }
#custom-field .typecho-label a {
display: block;
color: #444; }
#custom-field .typecho-label a:hover {
color: #467B96;
text-decoration: none; }
#custom-field table {
margin-top: 10px; }
#custom-field td {
@@ -1160,6 +1219,33 @@ a.operate-reply {
.mime-unknow {
background-position: 0 -160px; }
/* Logo 图标 */
.i-logo, .i-logo-s {
width: 169px;
height: 40px;
display: inline-block;
background: url("../img/typecho-logo.svg") no-repeat;
text-indent: -9999em;
-webkit-background-size: auto 40px;
-moz-background-size: auto 40px;
-o-background-size: auto 40px;
background-size: auto 40px;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=30);
opacity: 0.3; }
.i-logo:hover, .i-logo-s:hover {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=20);
opacity: 0.2; }
.i-logo-s {
width: 26px;
height: 26px;
-webkit-background-size: auto 26px;
-moz-background-size: auto 26px;
-o-background-size: auto 26px;
background-size: auto 26px;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=10);
opacity: 0.1; }
/*
* Editor
*/
@@ -1543,7 +1629,7 @@ div.token-input-dropdown ul li.token-input-selected-dropdown-item {
/*
* Hide only visually, but have it available for screenreaders: h5bp.com/v
*/
.visuallyhidden {
.sr-only {
border: 0;
height: 1px;
margin: -1px;
@@ -1553,11 +1639,11 @@ div.token-input-dropdown ul li.token-input-selected-dropdown-item {
width: 1px; }
/*
* Extends the .visuallyhidden class to allow the element to be focusable
* Extends the .sr-only class to allow the element to be focusable
* when navigated to via the keyboard: h5bp.com/p
*/
.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus {
.sr-only.focusable:active,
.sr-only.focusable:focus {
clip: auto;
height: auto;
margin: 0;
+1
View File
@@ -9,6 +9,7 @@ $(document).ready(function () {
btn.removeClass('i-caret-down').addClass('i-caret-right');
}
$(this).parent().toggleClass('fold');
return false;
});
function attachDeleteEvent (el) {
+18 -11
View File
@@ -4,7 +4,7 @@ $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"><i class="i-caret-right"></i> <?php _e('自定义字段'); ?></label>
<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%"/>
@@ -21,15 +21,22 @@ $defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaul
<?php endforeach; ?>
<?php foreach ($fields as $field): ?>
<tr>
<td><input type="text" name="fieldNames[]" value="<?php echo htmlspecialchars($field['name']); ?>" class="text-s w-100"></td>
<td>
<select name="fieldTypes[]" id="">
<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><textarea name="fieldValues[]" class="text-s w-100" rows="2"><?php echo htmlspecialchars($field[$field['type'] . '_value']); ?></textarea></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-xs"><?php _e('删除'); ?></button>
</td>
@@ -38,20 +45,20 @@ $defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaul
<?php if (empty($defaultFields) && empty($fields)): ?>
<tr>
<td>
<label for="title" class="visuallyhidden"><?php _e('字段名称'); ?></label>
<input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" class="text-s w-100">
<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="title" class="visuallyhidden"><?php _e('字段类型'); ?></label>
<select name="fieldTypes[]" id="">
<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="title" class="visuallyhidden"><?php _e('字段值'); ?></label>
<textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" class="text-s w-100" rows="2"></textarea>
<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-xs"><?php _e('删除'); ?></button>
@@ -61,6 +68,6 @@ $defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaul
</table>
<div class="description clearfix">
<button type="button" class="btn-xs operate-add"><?php _e('+添加字段'); ?></button>
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="">帮助文档</a>'); ?>
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="http://docs.typecho.org/help/custom-fields">帮助文档</a>'); ?>
</div>
</section>
+11 -2
View File
@@ -65,7 +65,7 @@ $(document).ready(function () {
// 设置markdown
Markdown.Extra.init(converter, {
extensions : 'all'
extensions : ["tables", "fenced_code_gfm", "def_list", "attr_list", "footnotes"]
});
// 自动跟随
@@ -143,7 +143,15 @@ $(document).ready(function () {
});
editor.hooks.chain('onPreviewRefresh', function () {
var diff = $('.diff', preview);
var diff = $('.diff', preview), scrolled = false;
$('img', preview).load(function () {
if (scrolled) {
preview.scrollTo(diff, {
offset : - 50
});
}
});
if (diff.length > 0) {
var p = diff.position(), lh = diff.parent().css('line-height');
@@ -153,6 +161,7 @@ $(document).ready(function () {
preview.scrollTo(diff, {
offset : - 50
});
scrolled = true;
}
}
});
+2 -5
View File
@@ -15,10 +15,7 @@ $header = '<link rel="stylesheet" href="' . Typecho_Common::url('css/normalize.c
$header = Typecho_Plugin::factory('admin/header.php')->header($header);
?><!DOCTYPE HTML>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<html class="no-js">
<head>
<meta charset="<?php $options->charset(); ?>">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
@@ -30,5 +27,5 @@ $header = Typecho_Plugin::factory('admin/header.php')->header($header);
</head>
<body<?php if (isset($bodyClass)) {echo ' class="' . $bodyClass . '"';} ?>>
<!--[if lt IE 9]>
<div class="message error browsehappy"><?php _e('您正在使用 <strong>旧版本</strong> 的浏览器. 为了更好的访问本页面, 请 <a href="http://browsehappy.com/">升级你的浏览器</a>'); ?>.</div>
<div class="message error browsehappy"><?php _e('当前网页 <strong>不支持</strong> 你正在使用的浏览器. 为了正常的访问, 请 <a href="http://browsehappy.com/">升级你的浏览器</a>'); ?>.</div>
<![endif]-->
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="110px" height="26px" viewBox="0 0 110 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<title>typecho-logo</title>
<description>Created with Sketch (http://www.bohemiancoding.com/sketch)</description>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<path d="M34.75,5.288 C34.288,6.542 33.76,7.73 32.22,7.862 L32,9.468 L33.562,9.468 L33.562,15.342 C33.562,16.882 33.54,18.994 36.972,18.994 C38.006,18.994 39.106,18.686 39.766,18.224 L39.106,16.53 C38.754,16.75 38.204,16.992 37.61,16.992 C36.708,16.992 36.18,16.596 36.18,15.254 L36.18,9.468 L38.886,9.468 L39.106,7.62 L36.18,7.62 L36.18,5.288 L34.75,5.288 Z M48.258,18.268 C48.258,20.27 47.444,21.502 45.42,21.502 C44.76,21.502 44.276,21.436 43.858,21.282 C43.462,21.128 43.352,20.908 43.352,20.49 L43.352,19.434 L41.262,19.61 L41.262,22.668 C42.186,23.13 44.012,23.394 45.398,23.394 C48.676,23.394 50.502,21.898 50.502,18.268 L50.502,7.62 L46.63,7.62 L46.63,9.424 L47.334,9.468 C47.752,9.468 47.884,9.644 47.884,10.128 L47.884,14.11 C47.884,15.254 47.07,16.288 45.53,16.288 C44.122,16.288 43.902,15.276 43.902,13.934 L43.902,7.62 L40.03,7.62 L40.03,9.424 L40.734,9.468 C41.108,9.49 41.284,9.622 41.284,10.084 L41.284,14.506 C41.284,17.102 42.494,18.312 44.694,18.312 C46.146,18.312 47.488,17.696 48.258,16.596 L48.258,18.268 Z M54,20.776 C54,21.326 53.78,21.458 53.362,21.502 L52.636,21.568 L52.636,23.24 L58.312,23.24 L58.312,21.502 L56.53,21.414 L56.53,18.378 C57.102,18.73 58.026,19.016 58.884,19.016 C61.788,19.016 63.702,16.926 63.702,12.878 C63.702,8.94 62.162,7.29 59.72,7.29 C57.85,7.29 56.64,8.302 56.244,9.05 L56.244,7.62 L52.526,7.62 L52.526,9.402 L53.45,9.468 C53.868,9.468 54,9.644 54,10.128 L54,20.776 Z M60.974,13.098 C60.974,15.012 60.336,16.926 58.466,16.926 C57.894,16.926 57.102,16.75 56.53,16.376 L56.53,11.316 C56.53,10.304 57.498,9.424 58.752,9.424 C59.918,9.424 60.974,10.172 60.974,13.098 Z M70.786,7.29 C67.178,7.29 65.352,10.15 65.352,13.406 C65.352,16.684 66.804,18.972 70.544,18.972 C72.612,18.972 74.064,18.048 74.416,17.74 L73.58,15.958 C73.052,16.332 72.106,16.926 70.808,16.926 C68.938,16.926 68.19,15.76 68.102,14.33 C70.698,14.308 74.372,13.736 74.372,10.348 C74.372,8.39 72.942,7.29 70.786,7.29 Z M71.952,10.392 C71.952,12.086 69.642,12.46 68.014,12.482 C68.08,10.854 68.872,9.16 70.632,9.16 C71.424,9.16 71.952,9.578 71.952,10.392 Z M81.192,16.97 C79.234,16.97 78.354,15.43 78.354,13.032 C78.354,10.59 79.256,9.27 81.016,9.27 C81.346,9.27 81.61,9.314 81.874,9.402 C82.27,9.534 82.336,9.732 82.336,10.15 L82.336,11.206 L84.36,11.052 L84.36,8.192 C83.304,7.62 82.248,7.29 80.928,7.29 C78.442,7.29 75.692,8.83 75.692,13.296 C75.692,16.948 77.606,18.994 80.84,18.994 C82.468,18.994 83.81,18.422 84.668,17.718 L83.722,16.024 C82.82,16.684 82.05,16.97 81.192,16.97 Z M87.286,16.222 C87.286,16.772 87.066,16.904 86.648,16.948 L85.922,17.014 L85.922,18.686 L91.158,18.686 L91.158,16.926 L89.904,16.86 L89.904,11.536 C89.904,10.392 90.718,9.314 92.258,9.314 C93.666,9.314 93.974,10.348 93.974,11.69 L93.974,16.222 C93.974,16.772 93.754,16.904 93.336,16.948 L92.61,17.014 L92.61,18.686 L97.846,18.686 L97.846,16.926 L96.592,16.86 L96.592,11.118 C96.592,8.522 95.294,7.29 93.094,7.29 C91.642,7.29 90.542,7.972 89.882,8.918 L89.882,3 L85.966,3 L85.966,4.826 L86.736,4.87 C87.154,4.892 87.286,5.024 87.286,5.508 L87.286,16.222 Z M98.924,13.142 C98.924,17.124 100.86,19.016 103.808,19.016 C106.712,19.016 109.066,17.08 109.066,12.856 C109.066,7.796 105.788,7.29 104.16,7.29 C101.894,7.29 98.924,8.566 98.924,13.142 Z M103.984,17.08 C101.872,17.08 101.586,14.88 101.586,12.834 C101.586,10.722 102.29,9.226 104.028,9.226 C105.788,9.226 106.382,10.744 106.382,13.208 C106.382,15.496 105.7,17.08 103.984,17.08 Z" id="typecho" fill="#000000" sketch:type="MSShapeGroup"></path>
<path d="M13,26 C3.36833333,26 0,22.631 0,13 C0,3.36866667 3.36833333,0 13,0 C22.6316667,0 26,3.36866667 26,13 C26,22.631 22.6316667,26 13,26 Z M6,9 L20,9 L20,7 L6,7 L6,9 Z M6,14 L16,14 L16,12 L6,12 L6,14 Z M6,19 L18,19 L18,17 L6,17 L6,19 Z" id="icon" fill="#000000" sketch:type="MSShapeGroup"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

+44 -49
View File
@@ -9,10 +9,12 @@ $stat = Typecho_Widget::widget('Widget_Stat');
<div class="container typecho-dashboard">
<?php include 'page-title.php'; ?>
<div class="colgroup typecho-page-main">
<div class="col-mb-12 col-tb-3 typecho-dashboard-nav" role="main">
<p class="intro"><?php _e('欢迎使用 Typecho, 您可以使用下面的链接开始您的 Blog 之旅:'); ?></p>
<ul class="intro-link">
<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>
<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): ?>
@@ -20,7 +22,7 @@ $stat = Typecho_Widget::widget('Widget_Stat');
<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>
<li><a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核评论'); ?></a>
<span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
</li>
<?php endif; ?>
@@ -34,36 +36,33 @@ $stat = Typecho_Widget::widget('Widget_Stat');
</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('options-general.php'); ?>"><?php _e('修改系统设置'); ?></a></li>
<li><a href="<?php $options->adminUrl('themes.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>
<h3><?php _e('统计信息'); ?></h3>
<div class="status">
<p><?php _e('目前有 <em>%s</em> 篇 Blog, 并有 <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>
<?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-6 typecho-dashboard-main" role="complementary">
<section>
<h3><?php _e('最近发的文章'); ?></h3>
<?php Typecho_Widget::widget('Widget_Contents_Post_Recent', 'pageSize=7')->to($posts); ?>
<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); ?>
<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>
<span>- <?php $posts->dateWord(); ?></span>
</li>
<?php endwhile; ?>
<?php else: ?>
@@ -71,41 +70,37 @@ $stat = Typecho_Widget::widget('Widget_Stat');
<?php endif; ?>
</ul>
</section>
</div>
<section>
<h3><?php _e('最新得到的回复'); ?></h3>
<div class="col-mb-12 col-tb-4" role="complementary">
<section class="latest-link">
<h3><?php _e('最近得到的回复'); ?></h3>
<ul>
<?php Typecho_Widget::widget('Widget_Comments_Recent', 'pageSize=7')->to($comments); ?>
<?php Typecho_Widget::widget('Widget_Comments_Recent', 'pageSize=10')->to($comments); ?>
<?php if($comments->have()): ?>
<?php while($comments->next()): ?>
<li>
<a href="<?php $comments->permalink(); ?>" class="title"><?php $comments->title(); ?></a>
<span>- <?php $comments->dateWord(); ?>, <?php $comments->author(true); ?></span>
<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 else: ?>
<li><em><?php _e('暂时没有回复'); ?></em></li>
<li><?php _e('暂时没有回复'); ?></li>
<?php endif; ?>
</ul>
</section>
</div>
<div class="col-mb-12 col-tb-3 typecho-dashboard-nav" role="complementary">
<?php $version = Typecho_Cookie::get('__typecho_check_version'); ?>
<?php if ($version && $version['available']): ?>
<div class="update-check">
<p>
<?php _e('您当前使用的版本是'); ?> <?php echo $version['current']; ?><br>
<strong><a href="<?php echo $version['link']; ?>"><?php _e('官方最新版本是'); ?> <?php echo $version['latest']; ?></a></strong>
</p>
</div>
<?php endif; ?>
<h3><?php _e('官方消息'); ?></h3>
<div id="typecho-message" class="intro-link">
<ul>
<li><?php _e('读取中...'); ?></li>
</ul>
</div>
<div class="col-mb-12 col-tb-4" role="complementary">
<section class="latest-link">
<h3><?php _e('官方最新日志'); ?></h3>
<div id="typecho-message">
<ul>
<li><?php _e('读取中...'); ?></li>
</ul>
</div>
</section>
</div>
</div>
</div>
@@ -118,7 +113,7 @@ include 'common-js.php';
<script>
$(document).ready(function () {
var ul = $('.intro-link ul'), cache = window.sessionStorage,
var ul = $('#typecho-message ul'), cache = window.sessionStorage,
html = cache ? cache.getItem('feed') : '',
update = cache ? cache.getItem('update') : '';
@@ -129,8 +124,8 @@ $(document).ready(function () {
$.get('<?php $options->index('/action/ajax?do=feed'); ?>', function (o) {
for (var i = 0; i < o.length; i ++) {
var item = o[i];
html += '<li><a href="' + item.link + '" target="_blank">' + item.title
+ '</a> <span>' + item.date + '</span></li>';
html += '<li><span>' + item.date + '</span> <a href="' + item.link + '" target="_blank">' + item.title
+ '</a></li>';
}
ul.html(html);
@@ -144,7 +139,7 @@ $(document).ready(function () {
+ '<?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>')
.prependTo('.typecho-dashboard-nav').effect('highlight');
.appendTo('.welcome-board').effect('highlight');
}
}
+10
View File
@@ -1086,7 +1086,16 @@ else
}
function _DoItalicsAndBold(text) {
// <strong> must go first:
text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,
"<strong>$2</strong>");
text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,
"<em>$2</em>");
return text;
/*
// <strong> must go first:
text = text.replace(/([\W_]|^)(\*\*|__)(?=\S)([^\r]*?\S[\*_]*)\2([\W_]|$)/g,
"$1<strong>$3</strong>$4");
@@ -1095,6 +1104,7 @@ else
"$1<em>$3</em>$4");
return text;
*/
}
function _DoBlockQuotes(text) {
+2134 -2134
View File
File diff suppressed because it is too large Load Diff
+6 -2
View File
@@ -502,6 +502,10 @@ $.TokenList = function (input, url_or_data, settings) {
item[settings.propertyToSearch] = input_box.val();
}
if (!item) {
return false;
}
// See if the token already exists and select it if we don't want duplicates
if(token_count > 0 && settings.preventDuplicates) {
var found_existing_token = null;
@@ -803,7 +807,7 @@ $.TokenList = function (input, url_or_data, settings) {
// Attach the success callback
ajax_params.success = function(results) {
if($.isFunction(settings.onResult)) {
results = settings.onResult.call(hidden_input, results);
results = settings.onResult.call(hidden_input, results, query);
}
cache.add(cache_key, settings.jsonContainer ? results[settings.jsonContainer] : results);
@@ -822,7 +826,7 @@ $.TokenList = function (input, url_or_data, settings) {
});
if($.isFunction(settings.onResult)) {
results = settings.onResult.call(hidden_input, results);
results = settings.onResult.call(hidden_input, results, query);
}
cache.add(cache_key, results);
populate_dropdown(query, results);
+1 -1
View File
@@ -172,7 +172,7 @@
single : false
}, options),
p = this.parent().css('position', 'relative'),
input = $('<input class="visuallyhidden" name="' + s.name + '" type="file" />').css({
input = $('<input class="sr-only" name="' + s.name + '" type="file" />').css({
opacity : 0,
cursor : 'pointer',
position : 'absolute',
+30 -27
View File
@@ -7,36 +7,39 @@ if ($user->hasLogin()) {
$rememberName = Typecho_Cookie::get('__typecho_remember_name');
Typecho_Cookie::delete('__typecho_remember_name');
$bodyClass = 'body-100';
include 'header.php';
?>
<div class="typecho-login">
<h1>Typecho</h1>
<form action="<?php $options->loginAction(); ?>" method="post" name="login" role="form">
<p>
<label for="name" class="visuallyhidden"><?php _e('用户名'); ?></label>
<input type="text" id="name" name="name" value="<?php echo $rememberName; ?>" placeholder="<?php _e('用户名'); ?>" class="text-l w-100" />
<div class="typecho-login-wrap">
<div class="typecho-login">
<h1><a href="http://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" />
</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('密码'); ?>" />
</p>
<p class="submit">
<button type="submit" class="btn-l w-100 primary"><?php _e('登录'); ?></button>
<input type="hidden" name="referer" value="<?php echo htmlspecialchars($request->get('referer')); ?>" />
</p>
<p>
<label for="remember"><input type="checkbox" name="remember" class="checkbox" value="1" id="remember" /> <?php _e('记住我'); ?></label>
</p>
</form>
<p class="more-link">
<a href="<?php $options->siteUrl(); ?>"><?php _e('返回首页'); ?></a>
<?php if($options->allowRegister): ?>
&bull;
<a href="<?php $options->registerUrl(); ?>"><?php _e('用户注册'); ?></a>
<?php endif; ?>
</p>
<p>
<label for="password" class="visuallyhidden"><?php _e('密码'); ?></label>
<input type="password" id="password" name="password" class="text-l w-100" placeholder="<?php _e('密码'); ?>" />
</p>
<p class="submit">
<button type="submit" class="btn-l w-100 primary"><?php _e('登录'); ?></button>
<input type="hidden" name="referer" value="<?php echo htmlspecialchars($request->get('referer')); ?>" />
</p>
<p>
<label for="remember"><input type="checkbox" name="remember" class="checkbox" value="1" id="remember" /> <?php _e('记住我'); ?></label>
</p>
</form>
<p class="more-link">
<a href="<?php $options->siteUrl(); ?>"><?php _e('返回首页'); ?></a>
<?php if($options->allowRegister): ?>
&bull;
<a href="<?php $options->registerUrl(); ?>"><?php _e('用户注册'); ?></a>
<?php endif; ?>
</p>
</div>
</div>
<?php
include 'common-js.php';
+61 -42
View File
@@ -48,38 +48,38 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typ
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<input type="checkbox" class="typecho-table-select-all" />
<div class="btn-group btn-drop">
<button class="dropdown-toggle btn-s" type="button" href="">选中项 <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $options->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $options->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $options->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $options->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<?php if('spam' == $request->get('status')): ?>
<li><a lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" href="<?php $options->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></a></li>
<?php endif; ?>
</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="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $options->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $options->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $options->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $options->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<?php if('spam' == $request->get('status')): ?>
<li><a lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" href="<?php $options->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></a></li>
<?php endif; ?>
</ul>
</div>
</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-s"><?php _e('筛选'); ?></button>
<?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-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div>
</div><!-- end .typecho-list-operate -->
<form method="post" name="manage_comments" class="operate-form">
<div class="typecho-table-wrap">
@@ -179,21 +179,40 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typ
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</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" />
<?php endif; ?>
</form>
<?php if($comments->have()): ?>
<ul class="typecho-pager">
<?php $comments->pageNav(); ?>
</ul>
<?php if(isset($request->cid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('cid')); ?>" name="cid" />
<?php endif; ?>
</div>
</div>
</form><!-- end .operate-form -->
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<input type="checkbox" class="typecho-table-select-all" />
<div class="btn-group btn-drop">
<button class="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $options->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $options->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $options->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $options->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<?php if('spam' == $request->get('status')): ?>
<li><a lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" href="<?php $options->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></a></li>
<?php endif; ?>
</ul>
</div>
</div>
<?php if($comments->have()): ?>
<ul class="typecho-pager">
<?php $comments->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
<?php
@@ -247,7 +266,7 @@ $(document).ready(function () {
} else {
var form = $('<form method="post" action="'
+ t.attr('rel') + '" class="comment-reply">'
+ '<p><label for="text" class="visuallyhidden"><?php _e('内容'); ?></label><textarea id="text" name="text" class="w-90 mono" rows="3"></textarea></p>'
+ '<p><label for="text" class="sr-only"><?php _e('内容'); ?></label><textarea id="text" name="text" class="w-90 mono" rows="3"></textarea></p>'
+ '<p><button type="submit" class="btn-s primary"><?php _e('回复'); ?></button> <button type="button" class="btn-s cancel"><?php _e('取消'); ?></button></p>'
+ '</form>').insertBefore($('.comment-action', td));
+43 -30
View File
@@ -14,25 +14,25 @@ $stat = Typecho_Widget::widget('Widget_Stat');
<div class="col-mb-12">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<input type="checkbox" class="typecho-table-select-all" />
<div class="btn-group btn-drop">
<button class="dropdown-toggle btn-s" type="button" href="">选中项 <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>" href="<?php $options->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</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-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div>
<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="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>" href="<?php $options->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</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-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
<form method="post" name="manage_medias" class="operate-form">
<div class="typecho-table-wrap">
@@ -65,7 +65,7 @@ $stat = Typecho_Widget::widget('Widget_Stat');
<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(); ?>"><i class="i-exlink" title="<?php _e('浏览 %s', $attachments->title); ?>"></i></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>
@@ -84,18 +84,31 @@ $stat = Typecho_Widget::widget('Widget_Stat');
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</form>
</table><!-- end .typecho-list-table -->
</div><!-- end .typecho-table-wrap -->
</form><!-- end .operate-form -->
<?php if($attachments->have()): ?>
<ul class="typecho-pager">
<?php $attachments->pageNav(); ?>
</ul>
<?php endif; ?>
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<input type="checkbox" class="typecho-table-select-all" />
<div class="btn-group btn-drop">
<button class="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>" href="<?php $options->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</div>
<?php if($attachments->have()): ?>
<ul class="typecho-pager">
<?php $attachments->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
</div>
</div>
</div><!-- end .typecho-page-main -->
</div>
</div>
+5 -5
View File
@@ -22,9 +22,9 @@ include 'menu.php';
<form method="post" name="manage_categories" class="operate-form">
<div class="typecho-list-operate clearfix">
<div class="operate">
<input type="checkbox" class="typecho-table-select-all" />
<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="dropdown-toggle btn-s" type="button" href="">选中项 <i class="i-caret-down"></i></button>
<button class="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('此分类下的所有内容将被删除, 你确认要删除这些分类吗?'); ?>" href="<?php $options->index('/action/metas-category-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<li><a lang="<?php _e('刷新分类可能需要等待较长时间, 你确认要刷新这些分类吗?'); ?>" href="<?php $options->index('/action/metas-category-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a></li>
@@ -63,7 +63,7 @@ include 'menu.php';
<tr id="mid-<?php $categories->theId(); ?>">
<td><input type="checkbox" value="<?php $categories->mid(); ?>" name="mid[]"/></td>
<td><a href="<?php echo $request->makeUriByRequest('mid=' . $categories->mid); ?>"><?php $categories->name(); ?></a>
<a href="<?php $categories->permalink(); ?>"><i class="i-exlink" title="<?php _e('浏览 %s', $categories->name); ?>"></i></a>
<a href="<?php $categories->permalink(); ?>" title="<?php _e('浏览 %s', $categories->name); ?>"><i class="i-exlink"></i></a>
</td>
<td><?php $categories->slug(); ?></td>
<td>
@@ -90,9 +90,9 @@ include 'menu.php';
<form method="post" name="manage_tags" class="operate-form">
<div class="typecho-list-operate clearfix">
<div class="operate">
<input type="checkbox" class="typecho-table-select-all" />
<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="dropdown-toggle btn-s" type="button" href="">选中项 <i class="i-caret-down"></i></button>
<button class="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些标签吗?'); ?>" href="<?php $options->index('/action/metas-tag-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
<li><a lang="<?php _e('刷新标签可能需要等待较长时间, 你确认要刷新这些标签吗?'); ?>" href="<?php $options->index('/action/metas-tag-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a></li>
+25 -25
View File
@@ -11,25 +11,26 @@ $stat = Typecho_Widget::widget('Widget_Stat');
<div class="colgroup typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<input type="checkbox" class="typecho-table-select-all" />
<div class="btn-group btn-drop">
<button class="dropdown-toggle btn-s" type="button" href="">选中项 <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些页面吗?'); ?>" href="<?php $options->index('/action/contents-page-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</div>
<div class="search" role="search">
<?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-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div>
<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="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些页面吗?'); ?>" href="<?php $options->index('/action/contents-page-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</div>
<div class="search" role="search">
<?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-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
<form method="post" name="manage_pages" class="operate-form">
<div class="typecho-table-wrap">
@@ -69,7 +70,7 @@ $stat = Typecho_Widget::widget('Widget_Stat');
}
?>
<?php if ('page_draft' != $pages->type): ?>
<a href="<?php $pages->permalink(); ?>"><i class="i-exlink" title="<?php _e('浏览 %s', htmlspecialchars($pages->title)); ?>"></i></a>
<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>
@@ -93,11 +94,10 @@ $stat = Typecho_Widget::widget('Widget_Stat');
<?php endif; ?>
</tbody>
</table>
</div>
</form>
</div>
</div>
</div><!-- end .typecho-table-wrap -->
</form><!-- end .operate-form -->
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
+45 -32
View File
@@ -13,33 +13,33 @@ $stat = Typecho_Widget::widget('Widget_Stat');
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<input type="checkbox" class="typecho-table-select-all" />
<div class="btn-group btn-drop">
<button class="dropdown-toggle btn-s" type="button" href="">选中项 <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>" href="<?php $options->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a></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="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>" href="<?php $options->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</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-s"><?php _e('筛选'); ?></button>
<?php if(isset($request->uid)): ?>
<?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-s"><?php _e('筛选'); ?></button>
<?php if(isset($request->uid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('uid')); ?>" name="uid" />
<?php endif; ?>
<?php endif; ?>
</div>
</form>
</div>
</div><!-- end .typecho-list-operate -->
<form method="post" name="manage_posts" class="operate-form">
<div class="typecho-table-wrap">
@@ -85,7 +85,7 @@ $stat = Typecho_Widget::widget('Widget_Stat');
}
?>
<?php if ('post_draft' != $posts->type): ?>
<a href="<?php $posts->permalink(); ?>"><i class="i-exlink" title="<?php _e('浏览 %s', htmlspecialchars($posts->title)); ?>" /></i></a>
<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>
@@ -118,16 +118,29 @@ $stat = Typecho_Widget::widget('Widget_Stat');
</tbody>
</table>
</div>
</form>
</form><!-- end .operate-form -->
<?php if($posts->have()): ?>
<ul class="typecho-pager">
<?php $posts->pageNav(); ?>
</ul>
<?php endif; ?>
</div>
</div>
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<input type="checkbox" class="typecho-table-select-all" />
<div class="btn-group btn-drop">
<button class="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>" href="<?php $options->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</div>
<?php if($posts->have()): ?>
<ul class="typecho-pager">
<?php $posts->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
+44 -32
View File
@@ -9,25 +9,25 @@ include 'menu.php';
<div class="colgroup typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<input type="checkbox" class="typecho-table-select-all" />
<div class="btn-group btn-drop">
<button class="dropdown-toggle btn-s" type="button" href="">选中项 <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>" href="<?php $options->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</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-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div>
<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="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>" href="<?php $options->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</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-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
<form method="post" name="manage_users" class="operate-form">
<div class="typecho-table-wrap">
@@ -57,7 +57,7 @@ include 'menu.php';
<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(); ?>"><i class="i-exlink" title="<?php _e('浏览 %s', $users->screenName); ?>"></i></a>
<a href="<?php $users->permalink(); ?>" title="<?php _e('浏览 %s', $users->screenName); ?>"><i class="i-exlink"></i></a>
</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>
@@ -83,18 +83,30 @@ include 'menu.php';
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
</form>
<?php if($users->have()): ?>
<ul class="typecho-pager">
<?php $users->pageNav(); ?>
</ul>
<?php endif; ?>
</div>
</div>
</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">
<input type="checkbox" class="typecho-table-select-all" />
<div class="btn-group btn-drop">
<button class="dropdown-toggle btn-s" type="button"><?php _e('<i class="sr-only">操作</i>选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>" href="<?php $options->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
</div>
</div>
<?php if($users->have()): ?>
<ul class="typecho-pager">
<?php $users->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
+5 -2
View File
@@ -83,8 +83,11 @@ $(document).ready(function() {
}
function fileUploadComplete (id, url, data) {
var img = $('.typecho-attachment-photo').get(0);
img.src = '<?php $attachment->attachment->url(); ?>?' + Math.random();
var img = $('.typecho-attachment-photo');
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 () {
+6 -1
View File
@@ -4,7 +4,12 @@
<?php $menu->output(); ?>
</nav>
<div class="operate">
<a 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(); ?>">网站</a>
<?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(); ?>">网站</a>
</div>
</div>
+1 -1
View File
@@ -7,7 +7,7 @@ include 'menu.php';
<div class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="colgroup typecho-page-main">
<div class="colgroup 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>
+1 -1
View File
@@ -6,7 +6,7 @@ include 'menu.php';
<div class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="colgroup typecho-page-main">
<div class="colgroup typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<?php Typecho_Widget::widget('Widget_Plugins_List_Activated')->to($activatedPlugins); ?>
<?php if ($activatedPlugins->have() || !empty($activatedPlugins->activatedPlugins)): ?>
+2 -1
View File
@@ -11,7 +11,8 @@ $stat = Typecho_Widget::widget('Widget_Stat');
<?php include 'page-title.php'; ?>
<div class="colgroup 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="avatar" src="http://www.gravatar.com/avatar/' . md5($user->mail) . '?s=220&r=X' .
<p><a href="http://gravatar.com/emails/" title="<?php _e('在 Gravatar 上修改头像'); ?>"><?php echo '<img class="profile-avatar" src="'
. ($request->isSecure() ? 'https://secure' : 'http://www') . '.gravatar.com/avatar/' . md5($user->mail) . '?s=220&r=X' .
'&d=" alt="' . $user->screenName . '" />'; ?></a></p>
<h2><?php $user->screenName(); ?><br><small><?php $user->name(); ?></small></h2>
<p><?php _e('目前有 <em>%s</em> 篇 Blog,并有 <em>%s</em> 条关于你的评论在已设定的 <em>%s</em> 个分类中.',
+24 -21
View File
@@ -9,30 +9,33 @@ $rememberMail = Typecho_Cookie::get('__typecho_remember_mail');
Typecho_Cookie::delete('__typecho_remember_name');
Typecho_Cookie::delete('__typecho_remember_mail');
$bodyClass = 'body-100';
include 'header.php';
?>
<div class="typecho-login">
<h1>Typecho</h1>
<form action="<?php $options->registerAction(); ?>" method="post" name="register" role="form">
<p>
<label for="name" class="visuallyhidden"><?php _e('用户名'); ?></label>
<input type="text" id="name" name="name" placeholder="<?php _e('用户名'); ?>" value="<?php echo $rememberName; ?>" class="text-l w-100" />
<div class="typecho-login-wrap">
<div class="typecho-login">
<h1><a href="http://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>
<input type="text" id="name" name="name" placeholder="<?php _e('用户名'); ?>" value="<?php echo $rememberName; ?>" class="text-l w-100" />
</p>
<p>
<label for="mail" class="sr-only"><?php _e('Email'); ?></label>
<input type="email" id="mail" name="mail" placeholder="<?php _e('Email'); ?>" value="<?php echo $rememberMail; ?>" class="text-l w-100" />
</p>
<p class="submit">
<button type="submit" class="btn-l w-100 primary"><?php _e('注册'); ?></button>
</p>
</form>
<p class="more-link">
<a href="<?php $options->siteUrl(); ?>"><?php _e('返回首页'); ?></a>
&bull;
<a href="<?php $options->adminUrl('login.php'); ?>"><?php _e('用户登录'); ?></a>
</p>
<p>
<label for="mail" class="visuallyhidden"><?php _e('Email'); ?></label>
<input type="email" id="mail" name="mail" placeholder="<?php _e('Email'); ?>" value="<?php echo $rememberMail; ?>" class="text-l w-100" />
</p>
<p class="submit">
<button type="submit" class="btn-l w-100 primary"><?php _e('注册'); ?></button>
</p>
</form>
<p class="more-link">
<a href="<?php $options->siteUrl(); ?>"><?php _e('返回首页'); ?></a>
&bull;
<a href="<?php $options->adminUrl('login.php'); ?>"><?php _e('用户登录'); ?></a>
</p>
</div>
</div>
<?php
include 'common-js.php';
+3 -2
View File
@@ -10,13 +10,14 @@
cursor: pointer;
@include border-radius(2px);
@include transition-duration(.4s);
// @include transition-property(background-color);
&:hover {
@include transition-duration(.4s);
background-color: darken($color, 6%);
}
&:active, &.active {
background-color: darken($color, 6%);
background-color: darken($color, 8%);
}
&:disabled {
background-color: lighten($color, 6%);
+11 -9
View File
@@ -2,17 +2,19 @@
* 注脚
*/
.typecho-foot {
padding: 4em 0;
padding: 4em 0 3em;
color: #999;
line-height: 1.8;
text-align: center;
}
.typecho-foot .resource {
color: #CCC;
.copyright p {
margin: 10px 0 0;
}
.resource {
color: #CCC;
}
.resource a {
margin: 0 3px;
color: #999;
}
}
.typecho-foot .resource a {
margin: 0 3px;
color: #999;
}
+7 -6
View File
@@ -9,7 +9,8 @@
.typecho-head-nav a {
color: #BBB;
}
.typecho-head-nav a:hover {
.typecho-head-nav a:hover,
.typecho-head-nav a:focus {
color: #FFF;
text-decoration: none;
}
@@ -56,18 +57,17 @@
#typecho-nav-list .child {
position: absolute;
left: -9999em;
top: 36px;
display: none;
margin: 0;
min-width: 160px;
max-width: 240px;
background: #202328;
overflow: hidden;
z-index: 250;
}
#typecho-nav-list .root:hover .child {
top: 36px;
left: 0;
display: block;
}
#typecho-nav-list .child li a {
@@ -81,7 +81,8 @@
line-height: 36px;
}
#typecho-nav-list .child li a:hover {
#typecho-nav-list .child li a:hover,
#typecho-nav-list .child li a:focus {
background: #292D33;
color: #FFF;
}
+4 -4
View File
@@ -11,7 +11,7 @@
* Hide only visually, but have it available for screenreaders: h5bp.com/v
*/
.visuallyhidden {
.sr-only {
border: 0;
height: 1px;
margin: -1px;
@@ -22,12 +22,12 @@
}
/*
* Extends the .visuallyhidden class to allow the element to be focusable
* Extends the .sr-only class to allow the element to be focusable
* when navigated to via the keyboard: h5bp.com/p
*/
.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus {
.sr-only.focusable:active,
.sr-only.focusable:focus {
clip: auto;
height: auto;
margin: 0;
+23 -1
View File
@@ -108,4 +108,26 @@ $icons-2x: sprite-map("icons-2x/*.png");
.mime-unknow {
@extend %i-16;
background-position: sprite-position($icons, mime-unknow);
}
}
/* Logo 图标 */
.i-logo, .i-logo-s {
width: 169px;
height: 40px;
display: inline-block;
background: url("../img/typecho-logo.svg") no-repeat;
text-indent: -9999em;
@include background-size(auto 40px);
@include opacity(.3);
&:hover {
@include opacity(.2);
}
}
.i-logo-s {
width: 26px;
height: 26px;
@include background-size(auto 26px);
@include opacity(.1);
}
+2 -5
View File
@@ -14,7 +14,6 @@
}
.error {
// border: 1px solid #FBC2C4;
background: #FBE3E4;
color: #8A1F11;
}
@@ -22,14 +21,12 @@
.notice {
background: #FFF6BF;
// border: 1px solid #FFD324;
color: #514721;
color: #8A6D3B;
}
.notice a { color: #514721; }
.notice a { color: #8A6D3B; }
.success {
background: #E6EFC2;
// border: 1px solid #C6D880;
color: #264409;
}
.success a { color: #264409; }
+6 -5
View File
@@ -4,9 +4,9 @@
.typecho-pager {
list-style: none;
margin: 30px 0 0;
float: right;
margin: 0;
padding: 0;
font-size: 1.14286em;
line-height: 1;
text-align: center;
zoom: 1;
@@ -15,13 +15,14 @@
.typecho-pager li {
display: inline-block;
margin: 0 3px;
height: 32px;
line-height: 32px;
height: 28px;
line-height: 28px;
}
.typecho-pager a {
display: block;
padding: 0 15px;
padding: 0 10px;
@include border-radius(2px);
}
.typecho-pager a:hover {
+73 -7
View File
@@ -32,7 +32,7 @@ a {
color: #467B96;
text-decoration: none;
&:hover {
color: #6DA1BB;
color: #499BC3;
text-decoration: underline;
}
}
@@ -43,6 +43,10 @@ code, pre, .mono {
.p { margin: 1em 0; }
.body-100 {
height: 100%;
}
a.balloon-button {
display: inline-block;
padding: 0 6px;
@@ -166,6 +170,11 @@ a.button:hover, a.balloon-button:hover {
padding-left: 1.5em;
}
.profile-avatar {
border: 1px dashed #D9D9D6;
max-width: 100%;
}
/** 增加配置面板内部的错误样式 by 70 */
@@ -238,15 +247,68 @@ a.button:hover, a.balloon-button:hover {
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 {
margin: 150px auto 0;
width: 280px;
.typecho-login-wrap {
display: table;
margin: 0 auto;
height: 100%;
}
.typecho-login {
display: table-cell;
padding-bottom: 100px;
width: 280px;
text-align: center;
vertical-align: middle;
h1 {
margin: 0 0 1em;
}
}
.typecho-login .more-link {
@@ -693,9 +755,13 @@ a.operate-reply {
.typecho-label {
margin: 0;
cursor: pointer;
&:hover {
color: #467B96;
a {
display: block;
color: #444;
&:hover {
color: #467B96;
text-decoration: none;
}
}
}
table {
+2 -2
View File
@@ -9,7 +9,7 @@ Typecho_Widget::widget('Widget_Themes_Files')->to($files);
<div class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="colgroup typecho-page-main">
<div class="colgroup 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>
@@ -29,7 +29,7 @@ Typecho_Widget::widget('Widget_Themes_Files')->to($files);
<div class="typecho-edit-theme">
<div class="col-mb-12 col-tb-8 col-9 content">
<form method="post" name="theme" id="theme" action="<?php $options->index('/action/themes-edit'); ?>">
<label for="content" class="visuallyhidden"><?php _e('编辑源码'); ?></label>
<label for="content" class="sr-only"><?php _e('编辑源码'); ?></label>
<textarea name="content" id="content" class="w-100 mono" <?php if(!$files->currentIsWriteable()): ?>readonly<?php endif; ?>><?php echo $files->currentContent(); ?></textarea>
<p class="submit">
<?php if($files->currentIsWriteable()): ?>
+1 -1
View File
@@ -7,7 +7,7 @@ include 'menu.php';
<div class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="colgroup typecho-page-main">
<div class="colgroup typecho-page-main" role="main">
<div class="col-mb-12">
<ul class="typecho-option-tabs fix-tabs clearfix">
<li class="current"><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a></li>
+1 -1
View File
@@ -7,7 +7,7 @@ include 'menu.php';
<div class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="colgroup typecho-page-main">
<div class="colgroup typecho-page-main" role="main">
<div class="col-mb-12">
<div id="typecho-welcome">
<form action="<?php echo Typecho_Router::url('do', array('action' => 'upgrade', 'widget' => 'Upgrade'),
+1 -1
View File
@@ -1,6 +1,5 @@
<?php
include 'common.php';
include 'header.php';
include 'menu.php';
?>
@@ -19,5 +18,6 @@ include 'menu.php';
<?php
include 'copyright.php';
include 'common-js.php';
include 'form-js.php';
include 'footer.php';
?>
+1 -1
View File
@@ -7,7 +7,7 @@ include 'menu.php';
<div class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="colgroup typecho-page-main">
<div class="colgroup typecho-page-main" role="main">
<div class="col-mb-12">
<div id="typecho-welcome" class="message">
<form action="<?php $options->adminUrl(); ?>" method="get">
+28 -2
View File
@@ -77,7 +77,22 @@ $(document).ready(function() {
noResultsText : '<?php _e('此标签不存在, 按回车创建'); ?>',
prePopulate : tagsPre,
onResult : function (result) {
onResult : function (result, query) {
if (!query) {
return result;
}
if (!result) {
result = [];
}
if (!result[0] || result[0]['id'] != query) {
result.unshift({
id : query,
tags : query
});
}
return result.slice(0, 5);
}
});
@@ -203,12 +218,23 @@ $(document).ready(function() {
return false;
});
// 高级选项控制
$('#advance-panel-btn').click(function() {
$('#advance-panel').toggle();
return false;
});
// 自动隐藏密码框
$('#visibility').change(function () {
var val = $(this).val(), password = $('#post-password');
console.log(val);
if ('password' == val) {
password.removeClass('hidden');
} else {
password.addClass('hidden');
}
});
// 草稿删除确认
$('.edit-draft-notice a').click(function () {
+9 -7
View File
@@ -17,7 +17,7 @@ Typecho_Widget::widget('Widget_Contents_Page_Edit')->to($page);
<?php endif; ?>
<p class="title">
<label for="title" class="visuallyhidden"><?php _e('标题'); ?></label>
<label for="title" class="sr-only"><?php _e('标题'); ?></label>
<input type="text" id="title" name="title" autocomplete="off" value="<?php echo htmlspecialchars($page->title); ?>" placeholder="<?php _e('标题'); ?>" class="w-100 text title" />
</p>
<?php $permalink = Typecho_Common::url($options->routingTable['page']['url'], $options->index);
@@ -30,11 +30,11 @@ Typecho_Widget::widget('Widget_Contents_Page_Edit')->to($page);
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($page->slug) . '" class="mono" />';
?>
<p class="mono url-slug">
<label for="slug" class="visuallyhidden"><?php _e('网址缩略名'); ?></label>
<label for="slug" class="sr-only"><?php _e('网址缩略名'); ?></label>
<?php echo preg_replace("/\{slug\}/i", $input, $permalink); ?>
</p>
<p>
<label for="text" class="visuallyhidden"><?php _e('页面内容'); ?></label>
<label for="text" class="sr-only"><?php _e('页面内容'); ?></label>
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text" name="text" class="w-100 mono"><?php echo htmlspecialchars($page->text); ?></textarea>
</p>
@@ -89,10 +89,12 @@ Typecho_Widget::widget('Widget_Contents_Page_Edit')->to($page);
<div id="advance-panel">
<section class="typecho-post-option visibility-option">
<label class="typecho-label"><?php _e('公开度'); ?></label>
<ul>
<li><input id="publish" value="publish" name="visibility" type="radio"<?php if ($page->status == 'publish' || !$page->status) { ?> checked="true"<?php } ?> /> <label for="publish"><?php _e('公开'); ?></label></li>
<li><input id="hidden" value="hidden" name="visibility" type="radio"<?php if ($page->status == 'hidden') { ?> checked="true"<?php } ?> /> <label for="hidden"><?php _e('隐藏'); ?></label></li>
</ul>
<p>
<select id="visibility" name="visibility">
<option value="publish"<?php if ($page->status == 'publish' || !$page->status): ?> selected<?php endif; ?>><?php _e('公开'); ?></option>
<option value="hidden"<?php if ($page->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
</select>
</p>
</section>
<section class="typecho-post-option allow-option">
+24 -17
View File
@@ -17,7 +17,7 @@ Typecho_Widget::widget('Widget_Contents_Post_Edit')->to($post);
<?php endif; ?>
<p class="title">
<label for="title" class="visuallyhidden"><?php _e('标题'); ?></label>
<label for="title" class="sr-only"><?php _e('标题'); ?></label>
<input type="text" id="title" name="title" autocomplete="off" value="<?php echo htmlspecialchars($post->title); ?>" placeholder="<?php _e('标题'); ?>" class="w-100 text title" />
</p>
<?php $permalink = Typecho_Common::url($options->routingTable['post']['url'], $options->index);
@@ -34,11 +34,11 @@ Typecho_Widget::widget('Widget_Contents_Post_Edit')->to($post);
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($post->slug) . '" class="mono" />';
?>
<p class="mono url-slug">
<label for="slug" class="visuallyhidden"><?php _e('网址缩略名'); ?></label>
<label for="slug" class="sr-only"><?php _e('网址缩略名'); ?></label>
<?php echo preg_replace("/\{slug\}/i", $input, $permalink); ?>
</p>
<p>
<label for="text" class="visuallyhidden"><?php _e('文章内容'); ?></label>
<label for="text" class="sr-only"><?php _e('文章内容'); ?></label>
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text" name="text" class="w-100 mono"><?php echo htmlspecialchars($post->text); ?></textarea>
</p>
@@ -100,25 +100,25 @@ Typecho_Widget::widget('Widget_Contents_Post_Edit')->to($post);
<div id="advance-panel">
<?php if($user->pass('editor', true)): ?>
<section class="typecho-post-option visibility-option">
<label class="typecho-label"><?php _e('公开度'); ?></label>
<ul>
<label for="visibility" class="typecho-label"><?php _e('公开度'); ?></label>
<p>
<select id="visibility" name="visibility">
<?php if ($user->pass('editor', true)): ?>
<li><input id="publish" value="publish" name="visibility" type="radio"<?php if (($post->status == 'publish' && !$post->password) || !$post->status) { ?> checked="true"<?php } ?> /> <label for="publish"><?php _e('公开'); ?></label></li>
<li><input id="hidden" value="hidden" name="visibility" type="radio"<?php if ($post->status == 'hidden') { ?> checked="true"<?php } ?> /> <label for="hidden"><?php _e('隐藏'); ?></label></li>
<li><input id="password" value="password" name="visibility" type="radio"<?php if ($post->password) { ?> checked="true"<?php } ?> /> <label for="password"><?php _e('密码保护'); ?> <input type="text" id="post-password" name="password" class="text-s" value="<?php $post->password(); ?>" size="16" /></label></li>
<li><input id="private" value="private" name="visibility" type="radio"<?php if ($post->status == 'private') { ?> checked="true"<?php } ?> /> <label for="private"><?php _e('私密'); ?></label></li>
<option value="publish"<?php if (($post->status == 'publish' && !$post->password) || !$post->status): ?> selected<?php endif; ?>><?php _e('公开'); ?></option>
<option value="hidden"<?php if ($post->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
<option value="password"<?php if (strlen($post->password) > 0): ?> selected<?php endif; ?>><?php _e('密码保护'); ?></option>
<option value="private"<?php if ($post->status == 'private'): ?> selected<?php endif; ?>><?php _e('私密'); ?></option>
<?php endif; ?>
<li><input id="waiting" value="waiting" name="visibility" type="radio"<?php if (!$user->pass('editor', true) || $post->status == 'waiting') { ?> checked="true"<?php } ?> /> <label for="waiting"><?php _e('待审核'); ?></label></li>
</ul>
<option value="waiting"<?php if (!$user->pass('editor', true) || $post->status == 'waiting'): ?> selected<?php endif; ?>><?php _e('待审核'); ?></option>
</select>
</p>
<p id="post-password"<?php if (strlen($post->password) == 0): ?> class="hidden"<?php endif; ?>>
<label for="protect-pwd" class="sr-only">内容密码</label>
<input type="text" name="password" id="protect-pwd" class="text-s" value="<?php $post->password(); ?>" size="16" placeholder="<?php _e('内容密码'); ?>" />
</p>
</section>
<?php endif; ?>
<section class="typecho-post-option">
<label for="trackback" class="typecho-label"><?php _e('引用通告'); ?></label>
<p><textarea id="trackback" class="w-100 mono" name="trackback" rows="3"></textarea></p>
<p class="description"><?php _e('每一行一个引用地址, 用回车隔开'); ?></p>
</section>
<section class="typecho-post-option allow-option">
<label class="typecho-label"><?php _e('权限控制'); ?></label>
<ul>
@@ -130,6 +130,13 @@ Typecho_Widget::widget('Widget_Contents_Post_Edit')->to($post);
<label for="allowFeed"><?php _e('允许在聚合中出现'); ?></label></li>
</ul>
</section>
<section class="typecho-post-option">
<label for="trackback" class="typecho-label"><?php _e('引用通告'); ?></label>
<p><textarea id="trackback" class="w-100 mono" name="trackback" rows="2"></textarea></p>
<p class="description"><?php _e('每一行一个引用地址, 用回车隔开'); ?></p>
</section>
<?php Typecho_Plugin::factory('admin/write-post.php')->advanceOption($post); ?>
</div><!-- end #advance-panel -->
+3 -1
View File
@@ -269,6 +269,7 @@ list($prefixVersion, $suffixVersion) = explode('/', $currentVersion);
/** 全局变量 */
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'theme', 'user' => 0, 'value' => 'default')));
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'theme:default', 'user' => 0, 'value' => 'a:2:{s:7:"logoUrl";N;s:12:"sidebarBlock";a:5:{i:0;s:15:"ShowRecentPosts";i:1;s:18:"ShowRecentComments";i:2;s:12:"ShowCategory";i:3;s:11:"ShowArchive";i:4;s:9:"ShowOther";}}')));
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'timezone', 'user' => 0, 'value' => _t('28800'))));
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'charset', 'user' => 0, 'value' => 'UTF-8')));
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'contentType', 'user' => 0, 'value' => 'text/html')));
@@ -279,6 +280,7 @@ list($prefixVersion, $suffixVersion) = explode('/', $currentVersion);
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'keywords', 'user' => 0, 'value' => 'typecho,php,blog')));
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'rewrite', 'user' => 0, 'value' => 0)));
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'frontPage', 'user' => 0, 'value' => 'recent')));
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'frontArchive', 'user' => 0, 'value' => 0)));
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsRequireMail', 'user' => 0, 'value' => 1)));
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsWhitelist', 'user' => 0, 'value' => 0)));
$installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsRequireURL', 'user' => 0, 'value' => 0)));
@@ -366,7 +368,7 @@ list($prefixVersion, $suffixVersion) = explode('/', $currentVersion);
if(_r('delete')) {
//删除原有数据
$dbPrefix = $config['prefix'];
$tableArray = array($dbPrefix . 'comments', $dbPrefix . 'contents', $dbPrefix . 'metas', $dbPrefix . 'options', $dbPrefix . 'relationships', $dbPrefix . 'users',);
$tableArray = array($dbPrefix . 'comments', $dbPrefix . 'contents', $dbPrefix . 'fields', $dbPrefix . 'metas', $dbPrefix . 'options', $dbPrefix . 'relationships', $dbPrefix . 'users',);
foreach($tableArray as $table) {
if($type == 'Mysql') {
$installDb->query("DROP TABLE IF EXISTS `{$table}`");
+281 -281
View File
@@ -1,282 +1,282 @@
The GNU General Public License (GPL)
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
The GNU General Public License (GPL)
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
-2
View File
@@ -21,7 +21,6 @@ package:
@echo 'package'
rm -Rf build/tools/
rm -Rf build/todo.txt
rm -Rf build/usr/plugins/*
rm -Rf build/admin/scss
rm -Rf build/admin/img/editor
rm -Rf build/admin/img/icons
@@ -62,7 +61,6 @@ install:
make update
rm -Rf build/tools/
rm -Rf build/todo.txt
rm -Rf build/usr/plugins/*
rm -Rf build/admin/scss
rm -Rf build/admin/img/editor
rm -Rf build/admin/img/icons
-213
View File
@@ -1,213 +0,0 @@
<?php
/**
* Akismet 反垃圾评论插件 for Typecho
*
* @package Akismet
* @author qining
* @version 1.1.4
* @link http://typecho.org
*/
class Akismet_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
if (false == Typecho_Http_Client::get()) {
throw new Typecho_Plugin_Exception(_t('对不起, 您的主机不支持 php-curl 扩展而且没有打开 allow_url_fopen 功能, 无法正常使用此功能'));
}
Typecho_Plugin::factory('Widget_Feedback')->comment = array('Akismet_Plugin', 'filter');
Typecho_Plugin::factory('Widget_Feedback')->trackback = array('Akismet_Plugin', 'filter');
Typecho_Plugin::factory('Widget_XmlRpc')->pingback = array('Akismet_Plugin', 'filter');
Typecho_Plugin::factory('Widget_Comments_Edit')->mark = array('Akismet_Plugin', 'mark');
return _t('请配置此插件的API KEY, 以使您的反垃圾策略生效');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate(){}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
$key = new Typecho_Widget_Helper_Form_Element_Textarea('key', NULL, NULL, _t('服务密钥'), _t('此密钥需要向服务提供商注册<br />
它是一个用于表明您合法用户身份的字符串'));
$form->addInput($key->addRule('required', _t('您必须填写一个服务密钥'))
->addRule(array('Akismet_Plugin', 'validate'), _t('您使用的服务密钥错误')));
$url = new Typecho_Widget_Helper_Form_Element_Text('url', NULL, 'http://rest.akismet.com',
_t('服务地址'), _t('这是反垃圾评论服务提供商的服务器地址<br />
我们推荐您使用 <a href="http://akismet.com">Akismet</a> 或者 <a href="http://antispam.typepad.com">Typepad</a> 的反垃圾服务'));
$form->addInput($url->addRule('url', _t('您使用的地址格式错误')));
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
/**
* 验证api的key值
*
* @access public
* @param string $key 服务密钥
* @return boolean
*/
public static function validate($key)
{
$options = Typecho_Widget::widget('Widget_Options');
$url = Typecho_Request::getInstance()->url;
$data = array(
'key' => $key,
'blog' => $options->siteUrl
);
$client = Typecho_Http_Client::get('Curl', 'Socket');
if (false != $client) {
$client->setData($data)
->setHeader('User-Agent', $options->generator . ' | Akismet/1.1')
->send(Typecho_Common::url('/1.1/verify-key', $url));
if ('valid' == $client->getResponseBody()) {
return true;
}
}
return false;
}
/**
* 标记评论状态时的插件接口
*
* @access public
* @param array $comment 评论数据的结构体
* @param Typecho_Widget $commentWidget 评论组件
* @param string $status 评论状态
* @return void
*/
public static function mark($comment, $commentWidget, $status)
{
if ('spam' == $comment['status'] && $status != 'spam') {
self::filter($comment, $commentWidget, NULL, 'submit-ham');
} else if ('spam' != $comment['status'] && $status == 'spam') {
self::filter($comment, $commentWidget, NULL, 'submit-spam');
}
}
/**
* 评论过滤器
*
* @access public
* @param array $comment 评论结构
* @param Typecho_Widget $post 被评论的文章
* @param array $result 返回的结果上下文
* @param string $api api地址
* @return void
*/
public static function filter($comment, $post, $result, $api = 'comment-check')
{
$comment = empty($result) ? $comment : $result;
$options = Typecho_Widget::widget('Widget_Options');
$url = $options->plugin('Akismet')->url;
$key = $options->plugin('Akismet')->key;
$allowedServerVars = 'comment-check' == $api ? array(
'SCRIPT_URI',
'HTTP_HOST',
'HTTP_USER_AGENT',
'HTTP_ACCEPT',
'HTTP_ACCEPT_LANGUAGE',
'HTTP_ACCEPT_ENCODING',
'HTTP_ACCEPT_CHARSET',
'HTTP_KEEP_ALIVE',
'HTTP_CONNECTION',
'HTTP_CACHE_CONTROL',
'HTTP_PRAGMA',
'HTTP_DATE',
'HTTP_EXPECT',
'HTTP_MAX_FORWARDS',
'HTTP_RANGE',
'CONTENT_TYPE',
'CONTENT_LENGTH',
'SERVER_SIGNATURE',
'SERVER_SOFTWARE',
'SERVER_NAME',
'SERVER_ADDR',
'SERVER_PORT',
'REMOTE_PORT',
'GATEWAY_INTERFACE',
'SERVER_PROTOCOL',
'REQUEST_METHOD',
'QUERY_STRING',
'REQUEST_URI',
'SCRIPT_NAME',
'REQUEST_TIME'
) : array();
$data = array(
'blog' => $options->siteUrl,
'user_ip' => $comment['ip'],
'user_agent' => $comment['agent'],
'referrer' => Typecho_Request::getInstance()->getReferer(),
'permalink' => $post->permalink,
'comment_type' => $comment['type'],
'comment_author' => $comment['author'],
'comment_author_email' => $comment['mail'],
'comment_author_url' => $comment['url'],
'comment_content' => $comment['text']
);
foreach ($allowedServerVars as $val) {
if (array_key_exists($val, $_SERVER)) {
$data[$val] = $_SERVER[$val];
}
}
try {
$client = Typecho_Http_Client::get();
if (false != $client && $key) {
$params = parse_url($url);
$url = $params['scheme'] . '://' . $key . '.' . $params['host'] . (isset($params['path']) ? $params['path'] : NULL);
$client->setHeader('User-Agent', $options->generator . ' | Akismet/1.1')
->setTimeout(5)
->setData($data)
->send(Typecho_Common::url('/1.1/' . $api, $url));
if ('true' == $client->getResponseBody()) {
$comment['status'] = 'spam';
}
}
} catch (Typecho_Http_Client_Exception $e) {
//do nothing
error_log($e->getMessage());
}
return $comment;
}
}
-124
View File
@@ -1,124 +0,0 @@
<?php
/**
* 增加评论黑名单(根据 IP 地址过滤)
*
* @package Block Comment
* @author 明城
* @version 0.0.1
* @link http://typecho.org
*/
class BlockComment_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
Typecho_Plugin::factory('Widget_Feedback')->comment = array('BlockComment_Plugin', 'filter');
Typecho_Plugin::factory('Widget_Feedback')->trackback = array('BlockComment_Plugin', 'filter');
Typecho_Plugin::factory('Widget_XmlRpc')->pingback = array('BlockComment_Plugin', 'filter');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate(){}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
$hosts = new Typecho_Widget_Helper_Form_Element_Textarea('hosts', NULL, NULL,
_t('地址列表'), _t('每行单个地址,请仔细匹配以免误封杀'));
$form->addInput($hosts);
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
/**
* 标记评论状态时的插件接口
*
* @access public
* @param array $comment 评论数据的结构体
* @param Typecho_Widget $commentWidget 评论组件
* @param string $status 评论状态
* @return void
*/
public static function mark($comment, $commentWidget, $status)
{
if ('spam' == $comment['status'] && $status != 'spam') {
self::filter($comment, $commentWidget, NULL, 'submit-ham');
} else if ('spam' != $comment['status'] && $status == 'spam') {
self::filter($comment, $commentWidget, NULL, 'submit-spam');
}
}
/**
* 评论过滤器
*
* @access public
* @param array $comment 评论结构
* @param Typecho_Widget $post 被评论的文章
* @param array $result 返回的结果上下文
* @param string $api api地址
* @return void
*/
public static function filter($comment, $post, $result, $api = 'comment-check')
{
$comment = empty($result) ? $comment : $result;
$options = Typecho_Widget::widget('Widget_Options');
$hosts = $options->plugin('BlockComment')->hosts;
$data = array(
'blog' => $options->siteUrl,
'user_ip' => $comment['ip'],
'user_agent' => $comment['agent'],
'referrer' => Typecho_Request::getInstance()->getReferer(),
'permalink' => $post->permalink,
'comment_type' => $comment['type'],
'comment_author' => $comment['author'],
'comment_author_email' => $comment['mail'],
'comment_author_url' => $comment['url'],
'comment_content' => $comment['text']
);
foreach(split("\n", $hosts) as $key => $value){
$value = trim($value);
if (strlen($value)) {
$regex = sprintf("/^%s/i", preg_quote($value));
// 如果提交者符合指定的 IP,则扔进垃圾评论中
if (preg_match($regex, $data['user_ip'])) {
$comment['status'] = 'spam';
break;
}
}
}
return $comment;
}
}
-768
View File
@@ -1,768 +0,0 @@
<?php
// vim: foldmethod=marker
/* Generic exception class
*/
class OAuthException extends Exception {/*{{{*/
// pass
}/*}}}*/
class OAuthConsumer {/*{{{*/
public $key;
public $secret;
function __construct($key, $secret, $callback_url=NULL) {/*{{{*/
$this->key = $key;
$this->secret = $secret;
$this->callback_url = $callback_url;
}/*}}}*/
function __toString() {/*{{{*/
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
}/*}}}*/
}/*}}}*/
class OAuthToken {/*{{{*/
// access tokens and request tokens
public $key;
public $secret;
/**
* key = the token
* secret = the token secret
*/
function __construct($key, $secret) {/*{{{*/
$this->key = $key;
$this->secret = $secret;
}/*}}}*/
/**
* generates the basic string serialization of a token that a server
* would respond to request_token and access_token calls with
*/
function to_string() {/*{{{*/
return "oauth_token=" . OAuthUtil::urlencode_rfc3986($this->key) .
"&oauth_token_secret=" . OAuthUtil::urlencode_rfc3986($this->secret);
}/*}}}*/
function __toString() {/*{{{*/
return $this->to_string();
}/*}}}*/
}/*}}}*/
class OAuthSignatureMethod {/*{{{*/
public function check_signature(&$request, $consumer, $token, $signature) {
$built = $this->build_signature($request, $consumer, $token);
return $built == $signature;
}
}/*}}}*/
class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {/*{{{*/
function get_name() {/*{{{*/
return "HMAC-SHA1";
}/*}}}*/
public function build_signature($request, $consumer, $token) {/*{{{*/
$base_string = $request->get_signature_base_string();
$request->base_string = $base_string;
$key_parts = array(
$consumer->secret,
($token) ? $token->secret : ""
);
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
$key = implode('&', $key_parts);
return base64_encode( hash_hmac('sha1', $base_string, $key, true));
}/*}}}*/
}/*}}}*/
class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {/*{{{*/
public function get_name() {/*{{{*/
return "PLAINTEXT";
}/*}}}*/
public function build_signature($request, $consumer, $token) {/*{{{*/
$sig = array(
OAuthUtil::urlencode_rfc3986($consumer->secret)
);
if ($token) {
array_push($sig, OAuthUtil::urlencode_rfc3986($token->secret));
} else {
array_push($sig, '');
}
$raw = implode("&", $sig);
// for debug purposes
$request->base_string = $raw;
return OAuthUtil::urlencode_rfc3986($raw);
}/*}}}*/
}/*}}}*/
class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {/*{{{*/
public function get_name() {/*{{{*/
return "RSA-SHA1";
}/*}}}*/
protected function fetch_public_cert(&$request) {/*{{{*/
// not implemented yet, ideas are:
// (1) do a lookup in a table of trusted certs keyed off of consumer
// (2) fetch via http using a url provided by the requester
// (3) some sort of specific discovery code based on request
//
// either way should return a string representation of the certificate
throw Exception("fetch_public_cert not implemented");
}/*}}}*/
protected function fetch_private_cert(&$request) {/*{{{*/
// not implemented yet, ideas are:
// (1) do a lookup in a table of trusted certs keyed off of consumer
//
// either way should return a string representation of the certificate
throw Exception("fetch_private_cert not implemented");
}/*}}}*/
public function build_signature(&$request, $consumer, $token) {/*{{{*/
$base_string = $request->get_signature_base_string();
$request->base_string = $base_string;
// Fetch the private key cert based on the request
$cert = $this->fetch_private_cert($request);
// Pull the private key ID from the certificate
$privatekeyid = openssl_get_privatekey($cert);
// Sign using the key
$ok = openssl_sign($base_string, $signature, $privatekeyid);
// Release the key resource
openssl_free_key($privatekeyid);
return base64_encode($signature);
} /*}}}*/
public function check_signature(&$request, $consumer, $token, $signature) {/*{{{*/
$decoded_sig = base64_decode($signature);
$base_string = $request->get_signature_base_string();
// Fetch the public key cert based on the request
$cert = $this->fetch_public_cert($request);
// Pull the public key ID from the certificate
$publickeyid = openssl_get_publickey($cert);
// Check the computed signature against the one passed in the query
$ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
// Release the key resource
openssl_free_key($publickeyid);
return $ok == 1;
} /*}}}*/
}/*}}}*/
class OAuthRequest {/*{{{*/
private $parameters;
private $http_method;
private $http_url;
// for debug purposes
public $base_string;
public static $version = '1.0';
function __construct($http_method, $http_url, $parameters=NULL) {/*{{{*/
@$parameters or $parameters = array();
$this->parameters = $parameters;
$this->http_method = $http_method;
$this->http_url = $http_url;
}/*}}}*/
/**
* attempt to build up a request from what was passed to the server
*/
public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {/*{{{*/
$scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") ? 'http' : 'https';
@$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'];
@$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
$request_headers = OAuthRequest::get_headers();
// let the library user override things however they'd like, if they know
// which parameters to use then go for it, for example XMLRPC might want to
// do this
if ($parameters) {
$req = new OAuthRequest($http_method, $http_url, $parameters);
} else {
// collect request parameters from query string (GET) and post-data (POST) if appropriate (note: POST vars have priority)
$req_parameters = $_GET;
if ($http_method == "POST" && @strstr($request_headers["Content-Type"], "application/x-www-form-urlencoded") ) {
$req_parameters = array_merge($req_parameters, $_POST);
}
// next check for the auth header, we need to do some extra stuff
// if that is the case, namely suck in the parameters from GET or POST
// so that we can include them in the signature
if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
$header_parameters = OAuthRequest::split_header($request_headers['Authorization']);
$parameters = array_merge($req_parameters, $header_parameters);
$req = new OAuthRequest($http_method, $http_url, $parameters);
} else $req = new OAuthRequest($http_method, $http_url, $req_parameters);
}
return $req;
}/*}}}*/
/**
* pretty much a helper function to set up the request
*/
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {/*{{{*/
@$parameters or $parameters = array();
$defaults = array("oauth_version" => OAuthRequest::$version,
"oauth_nonce" => OAuthRequest::generate_nonce(),
"oauth_timestamp" => OAuthRequest::generate_timestamp(),
"oauth_consumer_key" => $consumer->key);
$parameters = array_merge($defaults, $parameters);
if ($token) {
$parameters['oauth_token'] = $token->key;
}
return new OAuthRequest($http_method, $http_url, $parameters);
}/*}}}*/
public function set_parameter($name, $value) {/*{{{*/
$this->parameters[$name] = $value;
}/*}}}*/
public function get_parameter($name) {/*{{{*/
return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
}/*}}}*/
public function get_parameters() {/*{{{*/
return $this->parameters;
}/*}}}*/
/**
* Returns the normalized parameters of the request
*
* This will be all (except oauth_signature) parameters,
* sorted first by key, and if duplicate keys, then by
* value.
*
* The returned string will be all the key=value pairs
* concated by &.
*
* @return string
*/
public function get_signable_parameters() {/*{{{*/
// Grab all parameters
$params = $this->parameters;
// Remove oauth_signature if present
if (isset($params['oauth_signature'])) {
unset($params['oauth_signature']);
}
// Urlencode both keys and values
$keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
$values = OAuthUtil::urlencode_rfc3986(array_values($params));
$params = array_combine($keys, $values);
// Sort by keys (natsort)
uksort($params, 'strcmp');
// Generate key=value pairs
$pairs = array();
foreach ($params as $key=>$value ) {
if (is_array($value)) {
// If the value is an array, it's because there are multiple
// with the same key, sort them, then add all the pairs
natsort($value);
foreach ($value as $v2) {
$pairs[] = $key . '=' . $v2;
}
} else {
$pairs[] = $key . '=' . $value;
}
}
// Return the pairs, concated with &
return implode('&', $pairs);
}/*}}}*/
/**
* Returns the base string of this request
*
* The base string defined as the method, the url
* and the parameters (normalized), each urlencoded
* and the concated with &.
*/
public function get_signature_base_string() {/*{{{*/
$parts = array(
$this->get_normalized_http_method(),
$this->get_normalized_http_url(),
$this->get_signable_parameters()
);
$parts = OAuthUtil::urlencode_rfc3986($parts);
return implode('&', $parts);
}/*}}}*/
/**
* just uppercases the http method
*/
public function get_normalized_http_method() {/*{{{*/
return strtoupper($this->http_method);
}/*}}}*/
/**
* parses the url and rebuilds it to be
* scheme://host/path
*/
public function get_normalized_http_url() {/*{{{*/
$parts = parse_url($this->http_url);
$port = @$parts['port'];
$scheme = $parts['scheme'];
$host = $parts['host'];
$path = @$parts['path'];
$port or $port = ($scheme == 'https') ? '443' : '80';
if (($scheme == 'https' && $port != '443')
|| ($scheme == 'http' && $port != '80')) {
$host = "$host:$port";
}
return "$scheme://$host$path";
}/*}}}*/
/**
* builds a url usable for a GET request
*/
public function to_url() {/*{{{*/
$out = $this->get_normalized_http_url() . "?";
$out .= $this->to_postdata();
return $out;
}/*}}}*/
/**
* builds the data one would send in a POST request
*
* TODO(morten.fangel):
* this function might be easily replaced with http_build_query()
* and corrections for rfc3986 compatibility.. but not sure
*/
public function to_postdata() {/*{{{*/
$total = array();
foreach ($this->parameters as $k => $v) {
if (is_array($v)) {
foreach ($v as $va) {
$total[] = OAuthUtil::urlencode_rfc3986($k) . "[]=" . OAuthUtil::urlencode_rfc3986($va);
}
} else {
$total[] = OAuthUtil::urlencode_rfc3986($k) . "=" . OAuthUtil::urlencode_rfc3986($v);
}
}
$out = implode("&", $total);
return $out;
}/*}}}*/
/**
* builds the Authorization: header
*/
public function to_header() {/*{{{*/
$out ='Authorization: OAuth realm=""';
$total = array();
foreach ($this->parameters as $k => $v) {
if (substr($k, 0, 5) != "oauth") continue;
if (is_array($v)) throw new OAuthException('Arrays not supported in headers');
$out .= ',' . OAuthUtil::urlencode_rfc3986($k) . '="' . OAuthUtil::urlencode_rfc3986($v) . '"';
}
return $out;
}/*}}}*/
public function __toString() {/*{{{*/
return $this->to_url();
}/*}}}*/
public function sign_request($signature_method, $consumer, $token) {/*{{{*/
$this->set_parameter("oauth_signature_method", $signature_method->get_name());
$signature = $this->build_signature($signature_method, $consumer, $token);
$this->set_parameter("oauth_signature", $signature);
}/*}}}*/
public function build_signature($signature_method, $consumer, $token) {/*{{{*/
$signature = $signature_method->build_signature($this, $consumer, $token);
return $signature;
}/*}}}*/
/**
* util function: current timestamp
*/
private static function generate_timestamp() {/*{{{*/
return time();
}/*}}}*/
/**
* util function: current nonce
*/
private static function generate_nonce() {/*{{{*/
$mt = microtime();
$rand = mt_rand();
return md5($mt . $rand); // md5s look nicer than numbers
}/*}}}*/
/**
* util function for turning the Authorization: header into
* parameters, has to do some unescaping
*/
private static function split_header($header) {/*{{{*/
$pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
$offset = 0;
$params = array();
while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
$match = $matches[0];
$header_name = $matches[2][0];
$header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
$params[$header_name] = OAuthUtil::urldecode_rfc3986( $header_content );
$offset = $match[1] + strlen($match[0]);
}
if (isset($params['realm'])) {
unset($params['realm']);
}
return $params;
}/*}}}*/
/**
* helper to try to sort out headers for people who aren't running apache
*/
private static function get_headers() {/*{{{*/
if (function_exists('apache_request_headers')) {
// we need this to get the actual Authorization: header
// because apache tends to tell us it doesn't exist
return apache_request_headers();
}
// otherwise we don't have apache and are just going to have to hope
// that $_SERVER actually contains what we need
$out = array();
foreach ($_SERVER as $key => $value) {
if (substr($key, 0, 5) == "HTTP_") {
// this is chaos, basically it is just there to capitalize the first
// letter of every word that is not an initial HTTP and strip HTTP
// code from przemek
$key = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))));
$out[$key] = $value;
}
}
return $out;
}/*}}}*/
}/*}}}*/
class OAuthServer {/*{{{*/
protected $timestamp_threshold = 300; // in seconds, five minutes
protected $version = 1.0; // hi blaine
protected $signature_methods = array();
protected $data_store;
function __construct($data_store) {/*{{{*/
$this->data_store = $data_store;
}/*}}}*/
public function add_signature_method($signature_method) {/*{{{*/
$this->signature_methods[$signature_method->get_name()] =
$signature_method;
}/*}}}*/
// high level functions
/**
* process a request_token request
* returns the request token on success
*/
public function fetch_request_token(&$request) {/*{{{*/
$this->get_version($request);
$consumer = $this->get_consumer($request);
// no token required for the initial token request
$token = NULL;
$this->check_signature($request, $consumer, $token);
$new_token = $this->data_store->new_request_token($consumer);
return $new_token;
}/*}}}*/
/**
* process an access_token request
* returns the access token on success
*/
public function fetch_access_token(&$request) {/*{{{*/
$this->get_version($request);
$consumer = $this->get_consumer($request);
// requires authorized request token
$token = $this->get_token($request, $consumer, "request");
$this->check_signature($request, $consumer, $token);
$new_token = $this->data_store->new_access_token($token, $consumer);
return $new_token;
}/*}}}*/
/**
* verify an api call, checks all the parameters
*/
public function verify_request(&$request) {/*{{{*/
$this->get_version($request);
$consumer = $this->get_consumer($request);
$token = $this->get_token($request, $consumer, "access");
$this->check_signature($request, $consumer, $token);
return array($consumer, $token);
}/*}}}*/
// Internals from here
/**
* version 1
*/
private function get_version(&$request) {/*{{{*/
$version = $request->get_parameter("oauth_version");
if (!$version) {
$version = 1.0;
}
if ($version && $version != $this->version) {
throw new OAuthException("OAuth version '$version' not supported");
}
return $version;
}/*}}}*/
/**
* figure out the signature with some defaults
*/
private function get_signature_method(&$request) {/*{{{*/
$signature_method =
@$request->get_parameter("oauth_signature_method");
if (!$signature_method) {
$signature_method = "PLAINTEXT";
}
if (!in_array($signature_method,
array_keys($this->signature_methods))) {
throw new OAuthException(
"Signature method '$signature_method' not supported try one of the following: " . implode(", ", array_keys($this->signature_methods))
);
}
return $this->signature_methods[$signature_method];
}/*}}}*/
/**
* try to find the consumer for the provided request's consumer key
*/
private function get_consumer(&$request) {/*{{{*/
$consumer_key = @$request->get_parameter("oauth_consumer_key");
if (!$consumer_key) {
throw new OAuthException("Invalid consumer key");
}
$consumer = $this->data_store->lookup_consumer($consumer_key);
if (!$consumer) {
throw new OAuthException("Invalid consumer");
}
return $consumer;
}/*}}}*/
/**
* try to find the token for the provided request's token key
*/
private function get_token(&$request, $consumer, $token_type="access") {/*{{{*/
$token_field = @$request->get_parameter('oauth_token');
$token = $this->data_store->lookup_token(
$consumer, $token_type, $token_field
);
if (!$token) {
throw new OAuthException("Invalid $token_type token: $token_field");
}
return $token;
}/*}}}*/
/**
* all-in-one function to check the signature on a request
* should guess the signature method appropriately
*/
private function check_signature(&$request, $consumer, $token) {/*{{{*/
// this should probably be in a different method
$timestamp = @$request->get_parameter('oauth_timestamp');
$nonce = @$request->get_parameter('oauth_nonce');
$this->check_timestamp($timestamp);
$this->check_nonce($consumer, $token, $nonce, $timestamp);
$signature_method = $this->get_signature_method($request);
$signature = $request->get_parameter('oauth_signature');
$valid_sig = $signature_method->check_signature(
$request,
$consumer,
$token,
$signature
);
if (!$valid_sig) {
throw new OAuthException("Invalid signature");
}
}/*}}}*/
/**
* check that the timestamp is new enough
*/
private function check_timestamp($timestamp) {/*{{{*/
// verify that timestamp is recentish
$now = time();
if ($now - $timestamp > $this->timestamp_threshold) {
throw new OAuthException("Expired timestamp, yours $timestamp, ours $now");
}
}/*}}}*/
/**
* check that the nonce is not repeated
*/
private function check_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
// verify that the nonce is uniqueish
$found = $this->data_store->lookup_nonce($consumer, $token, $nonce, $timestamp);
if ($found) {
throw new OAuthException("Nonce already used: $nonce");
}
}/*}}}*/
}/*}}}*/
class OAuthDataStore {/*{{{*/
function lookup_consumer($consumer_key) {/*{{{*/
// implement me
}/*}}}*/
function lookup_token($consumer, $token_type, $token) {/*{{{*/
// implement me
}/*}}}*/
function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
// implement me
}/*}}}*/
function new_request_token($consumer) {/*{{{*/
// return a new token attached to this consumer
}/*}}}*/
function new_access_token($token, $consumer) {/*{{{*/
// return a new access token attached to this consumer
// for the user associated with this token if the request token
// is authorized
// should also invalidate the request token
}/*}}}*/
}/*}}}*/
/* A very naive dbm-based oauth storage
*/
class SimpleOAuthDataStore extends OAuthDataStore {/*{{{*/
private $dbh;
function __construct($path = "oauth.gdbm") {/*{{{*/
$this->dbh = dba_popen($path, 'c', 'gdbm');
}/*}}}*/
function __destruct() {/*{{{*/
dba_close($this->dbh);
}/*}}}*/
function lookup_consumer($consumer_key) {/*{{{*/
$rv = dba_fetch("consumer_$consumer_key", $this->dbh);
if ($rv === FALSE) {
return NULL;
}
$obj = unserialize($rv);
if (!($obj instanceof OAuthConsumer)) {
return NULL;
}
return $obj;
}/*}}}*/
function lookup_token($consumer, $token_type, $token) {/*{{{*/
$rv = dba_fetch("${token_type}_${token}", $this->dbh);
if ($rv === FALSE) {
return NULL;
}
$obj = unserialize($rv);
if (!($obj instanceof OAuthToken)) {
return NULL;
}
return $obj;
}/*}}}*/
function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
if (dba_exists("nonce_$nonce", $this->dbh)) {
return TRUE;
} else {
dba_insert("nonce_$nonce", "1", $this->dbh);
return FALSE;
}
}/*}}}*/
function new_token($consumer, $type="request") {/*{{{*/
$key = md5(time());
$secret = time() + time();
$token = new OAuthToken($key, md5(md5($secret)));
if (!dba_insert("${type}_$key", serialize($token), $this->dbh)) {
throw new OAuthException("doooom!");
}
return $token;
}/*}}}*/
function new_request_token($consumer) {/*{{{*/
return $this->new_token($consumer, "request");
}/*}}}*/
function new_access_token($token, $consumer) {/*{{{*/
$token = $this->new_token($consumer, 'access');
dba_delete("request_" . $token->key, $this->dbh);
return $token;
}/*}}}*/
}/*}}}*/
class OAuthUtil {/*{{{*/
public static function urlencode_rfc3986($input) {/*{{{*/
if (is_array($input)) {
return array_map(array('OAuthUtil','urlencode_rfc3986'), $input);
} else if (is_scalar($input)) {
return str_replace('+', ' ',
str_replace('%7E', '~', rawurlencode($input)));
} else {
return '';
}
}/*}}}*/
// This decode function isn't taking into consideration the above
// modifications to the encoding process. However, this method doesn't
// seem to be used anywhere so leaving it as is.
public static function urldecode_rfc3986($string) {/*{{{*/
return rawurldecode($string);
}/*}}}*/
}/*}}}*/
-144
View File
@@ -1,144 +0,0 @@
<?php
/**
* 支持用twitter帐号在blog中留言并同步到twitter上
*
* @package Connect to Twittter
* @author blankyao
* @version 1.0.0 Beta
* @link http://www.blankyao.cn
* @todo 文章自动推送到twitter twitter帐号注册
*/
include 'twitterOAuth.php';
class ConnectToTwitter_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate() {
Typecho_Plugin::factory('Widget_Feedback')->finishComment = array('ConnectToTwitter_Plugin', 'postToTwitter');
Typecho_Plugin::factory('Widget_Archive')->beforeRender = array('ConnectToTwitter_Plugin', 'initComment');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate() {
}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
$consumerKey = new Typecho_Widget_Helper_Form_Element_Text('consumerKey', NULL, '',
_t('Consumer Key'), _t('Your application consumer key from Twitter.com. '));
$form->addInput($consumerKey->addRule('required', _t('You must give the Consumer Key from Twitter.com')));
$consumerSecret = new Typecho_Widget_Helper_Form_Element_Text('consumerSecret', NULL, '',
_t('Consumer Secret'), _t('Your application consumer secret from Twitter.com. '));
$form->addInput($consumerSecret->addRule('required', _t('You must give the Consumer Key from Twitter.com')));
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
public static function initComment($api)
{
session_start();
$options = Typecho_Widget::widget('Widget_Options');
$config = $options->plugin('ConnectToTwitter');
//发送请求到twitter
if(isset($api->request->connect_to_twitter))
{
$to = new TwitterOAuth($config->consumerKey, $config->consumerSecret);
$tok = $to->getRequestToken();
Typecho_Cookie::set('oauth_request_token', $tok['oauth_token']);
Typecho_Cookie::set('oauth_request_token_secret', $tok['oauth_token_secret']);
/* Build the authorization URL */
$request_link = $to->getAuthorizeURL($tok['oauth_token']);
header('Location:'.$request_link);
}
//从twitter返回
if(isset($api->request->oauth_token)) {
if(Typecho_Cookie::get('oauth_request_token') && Typecho_Cookie::get('oauth_request_token_secret'))
{
$to = new TwitterOAuth($config->consumerKey, $config->consumerSecret, Typecho_Cookie::get('oauth_request_token'), Typecho_Cookie::get('oauth_request_token_secret'));
$tok = $to->getAccessToken();
Typecho_Cookie::set('oauth_access_token', $tok['oauth_token'], time()+60*60*24*30);
Typecho_Cookie::set('oauth_access_token_secret', $tok['oauth_token_secret'], time()+60*60*24*30);
$info_json = $to->OAuthRequest('https://twitter.com/account/verify_credentials.json', array(), 'GET');
$info = Typecho_Json::decode($info_json, true);
self::twitterLogin($info, $api);
}
}
}
//登录,暂时做为setcookie,以后要和用户帐号相关联
public static function twitterLogin($info, $api)
{
if (!empty($info['screen_name'])) {
Typecho_Cookie::set('__typecho_remember_author', $info['screen_name'], time()+60*60*24*30);
}
if (!empty($info['url'])) {
Typecho_Cookie::set('__typecho_remember_url', $info['url'], time()+60*60*24*30);
}
}
//发送信息到twitter
public static function postToTwitter($api)
{
if(Typecho_Cookie::get('oauth_access_token') && Typecho_Cookie::get('oauth_access_token_secret') && $api->request->post_to_twitter) {
$options = Typecho_Widget::widget('Widget_Options');
$config = $options->plugin('ConnectToTwitter');
$to = new TwitterOAuth($config->consumerKey, $config->consumerSecret, Typecho_Cookie::get('oauth_access_token'), Typecho_Cookie::get('oauth_access_token_secret'));
$url_array = array();
$url_array = explode('?', $api->request->getReferer());
$url = $url_array[0] . '#comment-' . $api->coid;
$post = $api->text . ' ( from ' . $url . ' ) ';
$twitter = $to->OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $post), 'POST');
}
return $comment;
}
function showButton()
{
if(Typecho_Cookie::get('oauth_access_token') && Typecho_Cookie::get('oauth_access_token_secret')) {
echo '<p><input type="checkbox" checked="" value="yes" id="post_to_twitter" name="post_to_twitter"/><label for="post_to_twitter">同时把留言更新到你的 Twitter</label></p>';
} else {
echo '<p><a href="?connect_to_twitter=yes"><img src="http://s3.amazonaws.com/static.whitleymedia/twitconnect.png" /></a></p>';
}
}
}
@@ -1,146 +0,0 @@
<?php
/*
* Abraham Williams (abraham@abrah.am) http://abrah.am
*
* Basic lib to work with Twitter's OAuth beta. This is untested and should not
* be used in production code. Twitter's beta could change at anytime.
*
* Code based on:
* Fire Eagle code - http://github.com/myelin/fireeagle-php-lib
* twitterlibphp - http://github.com/poseurtech/twitterlibphp
*/
/* Load OAuth lib. You can find it at http://oauth.net */
require_once('OAuth.php');
/**
* Twitter OAuth class
*/
class TwitterOAuth {/*{{{*/
/* Contains the last HTTP status code returned */
private $http_status;
/* Contains the last API call */
private $last_api_call;
/* Set up the API root URL */
public static $TO_API_ROOT = "https://twitter.com";
/**
* Set API URLS
*/
function requestTokenURL() { return self::$TO_API_ROOT.'/oauth/request_token'; }
function authorizeURL() { return self::$TO_API_ROOT.'/oauth/authorize'; }
function accessTokenURL() { return self::$TO_API_ROOT.'/oauth/access_token'; }
/**
* Debug helpers
*/
function lastStatusCode() { return $this->http_status; }
function lastAPICall() { return $this->last_api_call; }
/**
* construct TwitterOAuth object
*/
function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {/*{{{*/
$this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
if (!empty($oauth_token) && !empty($oauth_token_secret)) {
$this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
} else {
$this->token = NULL;
}
}/*}}}*/
/**
* Get a request_token from Twitter
*
* @returns a key/value array containing oauth_token and oauth_token_secret
*/
function getRequestToken() {/*{{{*/
$r = $this->oAuthRequest($this->requestTokenURL());
$token = $this->oAuthParseResponse($r);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}/*}}}*/
/**
* Parse a URL-encoded OAuth response
*
* @return a key/value array
*/
function oAuthParseResponse($responseString) {
$r = array();
foreach (explode('&', $responseString) as $param) {
$pair = explode('=', $param, 2);
if (count($pair) != 2) continue;
$r[urldecode($pair[0])] = urldecode($pair[1]);
}
return $r;
}
/**
* Get the authorize URL
*
* @returns a string
*/
function getAuthorizeURL($token) {/*{{{*/
if (is_array($token)) $token = $token['oauth_token'];
return $this->authorizeURL() . '?oauth_token=' . $token;
}/*}}}*/
/**
* Exchange the request token and secret for an access token and
* secret, to sign API calls.
*
* @returns array("oauth_token" => the access token,
* "oauth_token_secret" => the access secret)
*/
function getAccessToken($token = NULL) {/*{{{*/
$r = $this->oAuthRequest($this->accessTokenURL());
$token = $this->oAuthParseResponse($r);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}/*}}}*/
/**
* Format and sign an OAuth / API request
*/
function oAuthRequest($url, $args = array(), $method = NULL) {/*{{{*/
if (empty($method)) $method = empty($args) ? "GET" : "POST";
$req = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $args);
$req->sign_request($this->sha1_method, $this->consumer, $this->token);
switch ($method) {
case 'GET': return $this->http($req->to_url());
case 'POST': return $this->http($req->get_normalized_http_url(), $req->to_postdata());
}
}/*}}}*/
/**
* Make an HTTP request
*
* @return API results
*/
function http($url, $post_data = null) {/*{{{*/
$ch = curl_init();
if (defined("CURL_CA_BUNDLE_PATH")) curl_setopt($ch, CURLOPT_CAINFO, CURL_CA_BUNDLE_PATH);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//////////////////////////////////////////////////
///// Set to 1 to verify Twitter's SSL Cert //////
//////////////////////////////////////////////////
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
if (isset($post_data)) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
$response = curl_exec($ch);
$this->http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$this->last_api_call = $url;
curl_close ($ch);
return $response;
}/*}}}*/
}/*}}}*/
File diff suppressed because it is too large Load Diff
-262
View File
@@ -1,262 +0,0 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Baseline rule class for extension into a "real" parser component.
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Parse.inc.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* Baseline rule class for extension into a "real" parser component.
*
* Text_Wiki_Rule classes do not stand on their own; they are called by a
* Text_Wiki object, typcially in the transform() method. Each rule class
* performs three main activities: parse, process, and render.
*
* The parse() method takes a regex and applies it to the whole block of
* source text at one time. Each match is sent as $matches to the
* process() method.
*
* The process() method acts on the matched text from the source, and
* then processes the source text is some way. This may mean the
* creation of a delimited token using addToken(). In every case, the
* process() method returns the text that should replace the matched text
* from parse().
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Parse {
/**
*
* Configuration options for this parser rule.
*
* @access public
*
* @var string
*
*/
var $conf = array();
/**
*
* Regular expression to find matching text for this rule.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = null;
/**
*
* The name of this rule for new token array elements.
*
* @access public
*
* @var string
*
*/
var $rule = null;
/**
*
* A reference to the calling Text_Wiki object.
*
* This is needed so that each rule has access to the same source
* text, token set, URLs, interwiki maps, page names, etc.
*
* @access public
*
* @var object
*/
var $wiki = null;
/**
*
* Constructor for this parser rule.
*
* @access public
*
* @param object &$obj The calling "parent" Text_Wiki object.
*
*/
function Text_Wiki_Parse(&$obj)
{
// set the reference to the calling Text_Wiki object;
// this allows us access to the shared source text, token
// array, etc.
$this->wiki =& $obj;
// set the name of this rule; generally used when adding
// to the tokens array. strip off the Text_Wiki_Parse_ portion.
// text_wiki_parse_
// 0123456789012345
$tmp = substr(get_class($this), 16);
$this->rule = ucwords(strtolower($tmp));
// override config options for the rule if specified
if (isset($this->wiki->parseConf[$this->rule]) &&
is_array($this->wiki->parseConf[$this->rule])) {
$this->conf = array_merge(
$this->conf,
$this->wiki->parseConf[$this->rule]
);
}
}
/**
*
* Abstrct method to parse source text for matches.
*
* Applies the rule's regular expression to the source text, passes
* every match to the process() method, and replaces the matched text
* with the results of the processing.
*
* @access public
*
* @see Text_Wiki_Parse::process()
*
*/
function parse()
{
$this->wiki->source = preg_replace_callback(
$this->regex,
array(&$this, 'process'),
$this->wiki->source
);
}
/**
*
* Abstract method to generate replacements for matched text.
*
* @access public
*
* @param array $matches An array of matches from the parse() method
* as generated by preg_replace_callback. $matches[0] is the full
* matched string, $matches[1] is the first matched pattern,
* $matches[2] is the second matched pattern, and so on.
*
* @return string The processed text replacement; defaults to the
* full matched string (i.e., no changes to the text).
*
* @see Text_Wiki_Parse::parse()
*
*/
function process(&$matches)
{
return $matches[0];
}
/**
*
* Simple method to safely get configuration key values.
*
* @access public
*
* @param string $key The configuration key.
*
* @param mixed $default If the key does not exist, return this value
* instead.
*
* @return mixed The configuration key value (if it exists) or the
* default value (if not).
*
*/
function getConf($key, $default = null)
{
if (isset($this->conf[$key])) {
return $this->conf[$key];
} else {
return $default;
}
}
/**
*
* Extract 'attribute="value"' portions of wiki markup.
*
* This kind of markup is typically used only in macros, but is useful
* anywhere.
*
* The syntax is pretty strict; there can be no spaces between the
* option name, the equals, and the first double-quote; the value
* must be surrounded by double-quotes. You can escape characters in
* the value with a backslash, and the backslash will be stripped for
* you.
*
* @access public
*
* @param string $text The "attributes" portion of markup.
*
* @return array An associative array of key-value pairs where the
* key is the option name and the value is the option value.
*
*/
function getAttrs($text)
{
// find the =" sections;
$tmp = explode('="', trim($text));
// basic setup
$k = count($tmp) - 1;
$attrs = array();
$key = null;
// loop through the sections
foreach ($tmp as $i => $val) {
// first element is always the first key
if ($i == 0) {
$key = trim($val);
continue;
}
// find the last double-quote in the value.
// the part to the left is the value for the last key,
// the part to the right is the next key name
$pos = strrpos($val, '"');
$attrs[$key] = stripslashes(substr($val, 0, $pos));
$key = trim(substr($val, $pos+1));
}
return $attrs;
}
}
?>
-67
View File
@@ -1,67 +0,0 @@
<?php
/**
*
* Parses for signatures.
* This class implements a Text_Wiki rule to find sections of the source
* text that are signatures. A signature is any line starting with exactly
* two - signs.
*
* @category Text
*
* @package Text_Wiki
*
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Address.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Address extends Text_Wiki_Parse {
/**
*
* The regular expression used to find source text matching this
* rule.
*
* @access public
*
* @var string
*
*/
var $regex = '/^--([^-].*)$/m';
/**
*
* Generates a token entry for the matched text. Token options are:
*
* 'start' => The starting point of the signature.
*
* 'end' => The ending point of the signature.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A delimited token number to be used as a placeholder in
* the source text.
*
*/
function process(&$matches)
{
$start = $this->wiki->addToken(
$this->rule, array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule, array('type' => 'end')
);
return "\n" . $start . trim($matches[1]) . $end;
}
}
?>
-176
View File
@@ -1,176 +0,0 @@
<?php
/**
*
* Parse for block-quoted text.
*
* Find source text marked as a blockquote, identified by any number of
* greater-than signs '>' at the start of the line, followed by an
* optional space, and then the quote text; each '>' indicates an
* additional level of quoting.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Blockquote.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Blockquote extends Text_Wiki_Parse {
/**
*
* Regex for parsing the source text.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/\n(([>:]).*\n)(?!([>:]))/Us';
/**
*
* Generates a replacement for the matched text.
*
* Token options are:
*
* 'type' =>
* 'start' : the start of a blockquote
* 'end' : the end of a blockquote
*
* 'level' => the indent level (0 for the first level, 1 for the
* second, etc)
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A series of text and delimited tokens marking the different
* list text and list elements.
*
*/
function process(&$matches)
{
// the replacement text we will return to parse()
$return = '';
// the list of post-processing matches
$list = array();
// $matches[1] is the text matched as a list set by parse();
// create an array called $list that contains a new set of
// matches for the various list-item elements.
preg_match_all(
'=^([>:]+)(.*?\n)=ms',
$matches[1],
$list,
PREG_SET_ORDER
);
// a stack of starts and ends; we keep this so that we know what
// indent level we're at.
$stack = array();
// loop through each list-item element.
foreach ($list as $key => $val) {
// $val[0] is the full matched list-item line
// $val[1] is the number of initial '>' chars (indent level)
// $val[2] is the quote text
// we number levels starting at 1, not zero
$level = strlen($val[1]);
// get the text of the line
$text = trim($val[2]);
// add a level to the list?
while ($level > count($stack)) {
$css = ($val[1][count($stack)] == ':') ? 'remark' : '';
// the current indent level is greater than the number
// of stack elements, so we must be starting a new
// level. push the new level onto the stack with a
// dummy value (boolean true)...
array_push($stack, true);
$return .= "\n\n";
// ...and add a start token to the return.
$return .= $this->wiki->addToken(
$this->rule,
array(
'type' => 'start',
'level' => $level - 1,
'css' => $css
)
);
$return .= "\n\n";
}
// remove a level?
while (count($stack) > $level) {
// as long as the stack count is greater than the
// current indent level, we need to end list types.
// continue adding end-list tokens until the stack count
// and the indent level are the same.
array_pop($stack);
$return .= "\n\n";
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => 'end',
'level' => count($stack)
)
);
$return .= "\n\n";
}
// add the line text.
$return .= $text . "\n";
}
// the last line may have been indented. go through the stack
// and create end-tokens until the stack is empty.
$return .= "\n\n";
while (count($stack) > 0) {
array_pop($stack);
$return .= "\n\n";
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => 'end',
'level' => count($stack)
)
);
$return .= "\n\n";
}
// we're done! send back the replacement text.
return "\n\n$return\n\n";
}
}
?>
-81
View File
@@ -1,81 +0,0 @@
<?php
/**
*
* Parses for bold text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Justin Patrin <papercrane@reversefold.com>
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Box.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
/**
*
* Parses for bold text.
*
* This class implements a Text_Wiki_Rule to find source text marked for
* strong emphasis (bold) as defined by text surrounded by three
* single-quotes. On parsing, the text itself is left in place, but the
* starting and ending instances of three single-quotes are replaced with
* tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Justin Patrin <papercrane@reversefold.com>
* @author Paul M. Jones <pmjones@php.net>
*
*/
class Text_Wiki_Parse_Box extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/\n\[\d+\].*/s';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* emphasized text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A pair of delimited tokens to be used as a placeholder in
* the source text surrounding the text to be emphasized.
*
*/
function process(&$matches)
{
$start = $this->wiki->addToken($this->rule, array('type' => 'start', 'css' => 'footnotes'));
$end = $this->wiki->addToken($this->rule, array('type' => 'end'));
return $start . $matches[0] . "\n" . $end . "\n\n";
}
}
?>
-73
View File
@@ -1,73 +0,0 @@
<?php
/**
*
* Parses for explicit line breaks.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Break.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
/**
*
* Parses for explicit line breaks.
*
* This class implements a Text_Wiki_Parse to mark forced line breaks in the
* source text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
*/
class Text_Wiki_Parse_Break extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = "/[ \n]*([\\\][\\\]|\%\%\%)[ \n]*/";
var $regex = "/ *([\\\][\\\]|\%\%\%)\n?/";
/**
*
* Generates a replacement token for the matched text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A delimited token to be used as a placeholder in
* the source text.
*
*/
function process(&$matches)
{
return $this->wiki->addToken($this->rule);
}
}
?>
-78
View File
@@ -1,78 +0,0 @@
<?php
/**
*
* Parses for centered text.
*
* This class implements a Text_Wiki_Parse to find source text marked to
* be a center element, as defined by text on a line by itself prefixed
* with an exclamation mark (!).
* The centered text itself is left in the source, but is prefixed and
* suffixed with delimited tokens marking its start and end.
*
* @category Text
*
* @package Text_Wiki
*
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Center.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Center extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/^! *(.*?)$/m';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* centered text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the centered text.
*
*/
function process(&$matches)
{
$start = $this->wiki->addToken(
$this->rule,
array(
'type' => 'start'
)
);
$end = $this->wiki->addToken(
$this->rule,
array(
'type' => 'end'
)
);
return $start . trim($matches[1]) . $end . "\n\n";
}
}
?>
-78
View File
@@ -1,78 +0,0 @@
<?php
/**
*
* Parses for italic text.
*
* This class implements a Text_Wiki_Parse to find source text marked for
* underlined as defined by text surrounded by two '_'.
* On parsing, the text itself is left in place, but the starting and ending
* instances of two '^' are replaced with tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Delete extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = "/__(.*?)__/";
var $regex = "/(?:\-\-(.+?)\-\-|(?:(?<=[\W-\xFF])\-(?![ \-]))(.+?)(?:(?<![ \-])\_(?=[\W-\xFF])))/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* superscript text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the text to be
* superscripted.
*
*/
function process(&$matches)
{
$text = $matches[1] ? $matches[1] : $matches[2];
if (! $this->wiki->checkInnerTags($text)) {
return $matches[0];
}
$start = $this->wiki->addToken(
'Delete', // $this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
'Delete', // $this->rule,
array('type' => 'end')
);
return $start . $text . $end;
}
}
?>
-68
View File
@@ -1,68 +0,0 @@
<?php
/**
*
* Parses for Text_Wiki delimiter characters already in the source text.
*
* This class implements a Text_Wiki_Parse to find instances of the delimiter
* character already embedded in the source text; it extracts them and replaces
* them with a delimited token, then renders them as the delimiter itself
* when the target format is XHTML.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Delimiter.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Delimiter extends Text_Wiki_Parse {
/**
*
* Constructor. Overrides the Text_Wiki_Parse constructor so that we
* can set the $regex property dynamically (we need to include the
* Text_Wiki $delim character.
*
* @param object &$obj The calling "parent" Text_Wiki object.
*
* @param string $name The token name to use for this rule.
*
*/
function Text_Wiki_Parse_Delimiter(&$obj)
{
parent::Text_Wiki_Parse($obj);
$this->regex = '/' . $this->wiki->delim . '/';
}
/**
*
* Generates a token entry for the matched text. Token options are:
*
* 'text' => The full matched text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A delimited token number to be used as a placeholder in
* the source text.
*
*/
function process(&$matches)
{
return $this->wiki->addToken(
$this->rule,
array('text' => $this->wiki->delim)
);
}
}
?>
-78
View File
@@ -1,78 +0,0 @@
<?php
/**
*
* Parses for italic text.
*
* This class implements a Text_Wiki_Parse to find source text marked for
* emphasis (italics) as defined by text surrounded by two slashes.
* On parsing, the text itself is left in place, but the starting and ending
* instances of two single-quotes are replaced with tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Emphasis extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = "/\/\/(.*?)\/\//";
var $regex = "/(?:\/\/(.+?)\/\/|(?:(?<=[\W_\xFF])\/(?![ \/]))(.+?)(?:(?<![ \/])\/(?=[\W_\xFF])))/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* emphasized text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the text to be
* emphasized.
*
*/
function process(&$matches)
{
$text = $matches[1] ? $matches[1] : $matches[2];
if (! $this->wiki->checkInnerTags($text)) {
return $matches[0];
}
$start = $this->wiki->addToken(
$this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule,
array('type' => 'end')
);
return $start . $text . $end;
}
}
?>
-83
View File
@@ -1,83 +0,0 @@
<?php
/**
*
* Parses for bold text.
*
* This class implements a Text_Wiki_Rule to find source text marked for
* strong emphasis (bold) as defined by text surrounded by two
* stars. On parsing, the text itself is left in place, but the
* starting and ending instances of two stars are replaced with
* tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Footnote.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Footnote extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = "/(\n)*\[([0-9]+)\]/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* emphasized text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A pair of delimited tokens to be used as a placeholder in
* the source text surrounding the text to be emphasized.
*
*/
function process(&$matches)
{
$id = $matches[2];
if ($matches[1] == "\n") {
$matches[1] = "\n\n";
$name = "fn$id";
$href = "#ref$id";
}
else {
$name = "ref$id";
$href = "#fn$id";
}
$token = $this->wiki->addToken(
'Url',
array('text' => "[$id]", 'href' => $href, 'name' => $name, 'type' => 'inline')
);
return $matches[1] . $token;
}
}
?>
-97
View File
@@ -1,97 +0,0 @@
<?php
/**
*
* Parses for heading text.
*
* This class implements a Text_Wiki_Parse to find source text marked to
* be a heading element, as defined by text on a line by itself prefixed
* with a number of equasl signs (=), determining the heading level.
* Equal signs at the end of the line are silently removed.
* The heading text itself is left in the source, but is prefixed and
* suffixed with delimited tokens marking the start and end of the heading.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Heading.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Heading extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/^(={1,6}) *(.*?) *=*$/m';
var $conf = array(
'id_prefix' => 'toc'
);
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* heading text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the heading text.
*
*/
function process(&$matches)
{
// keep a running count for header IDs. we use this later
// when constructing TOC entries, etc.
static $id;
if (! isset($id)) {
$id = 0;
}
$prefix = htmlspecialchars($this->getConf('id_prefix'));
$start = $this->wiki->addToken(
$this->rule,
array(
'type' => 'start',
'level' => strlen($matches[1]),
'text' => trim($matches[2]),
'id' => $prefix . $id ++
)
);
$end = $this->wiki->addToken(
$this->rule,
array(
'type' => 'end',
'level' => strlen($matches[1])
)
);
return $start . trim($matches[2]) . $end . "\n\n";
}
}
?>
-58
View File
@@ -1,58 +0,0 @@
<?php
/**
*
* Parses for horizontal ruling lines.
*
* This class implements a Text_Wiki_Parse to find source text marked to
* be a horizontal rule, as defined by four dashed on their own line.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Horiz.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Horiz extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/^([-]{4,})$/m';
/**
*
* Generates a replacement token for the matched text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token marking the horizontal rule.
*
*/
function process(&$matches)
{
return "\n" . $this->wiki->addToken($this->rule) . "\n";
}
}
?>
-66
View File
@@ -1,66 +0,0 @@
<?php
/**
*
* Parse for images in the source text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Image.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Image extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/{{(.*)(\|(.*))?}}/U';
/**
*
* Generates a replacement token for the matched text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token marking the horizontal rule.
*
*/
function process(&$matches)
{
$src = trim($matches[1]);
$src = ltrim($src, '/');
$alt = isset($matches[3]) ? trim($matches[3]) : null;
if (!$alt) $alt = $src;
return $this->wiki->addToken(
$this->rule,
array(
'src' => $src,
'attr' => array('alt' => $alt, 'title' => $alt)
)
);
}
}
?>
-244
View File
@@ -1,244 +0,0 @@
<?php
/**
*
* Parses for bulleted and numbered lists.
*
* This class implements a Text_Wiki_Parse to find source text marked as
* a bulleted or numbered list. In short, if a line starts with '*' then
* it is a bullet list item; if a line starts with '#' then it is a
* number list item. Multiple * or # indicate an indented sub-list.
* The list items must be on sequential lines, and are ended by blank lines.
* Using a non-* non-# character at the beginning of a line ends the list.
* Note that single newline characters may be eaten beforehand by other rules.
*
* @category Text
*
* @package Text_Wiki
*
* @author Justin Patrin <papercrane@reversefold.com>
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: List.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_List extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/\n((\*[^\#\-\*]|\-[^\-\d\*\#]|\#[^\#\-\*]).*?)\n(?![\*\-#])/s';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' =>
* 'bullet_start' : the start of a bullet list
* 'bullet_end' : the end of a bullet list
* 'number_start' : the start of a number list
* 'number_end' : the end of a number list
* 'item_start' : the start of item text (bullet or number)
* 'item_end' : the end of item text (bullet or number)
* 'unknown' : unknown type of list or item
*
* 'level' => the indent level (0 for the first level, 1 for the
* second, etc)
*
* 'count' => the list item number at this level. not needed for
* xhtml, but very useful for PDF and RTF.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A series of text and delimited tokens marking the different
* list text and list elements.
*
*/
function process(&$matches)
{
// the replacement text we will return
$return = '';
// the list of post-processing matches
$list = array();
// a stack of list-start and list-end types; we keep this
// so that we know what kind of list we're working with
// (bullet or number) and what indent level we're at.
$stack = array();
// the item count is the number of list items for any
// given list-type on the stack
$itemcount = array();
// have we processed the very first list item?
$pastFirst = false;
// populate $list with this set of matches. $matches[1] is the
// text matched as a list set by parse().
preg_match_all(
'/^((\*|\-|#)+) *(.*?)$/ms',
$matches[1],
$list,
PREG_SET_ORDER
);
if (count($list) === 1 && $matches[0][0] === '*' && $matches[0][1] !== ' ' && strpos($matches[0], '*', 1)) {
return $matches[0];
}
// loop through each list-item element.
foreach ($list as $key => $val) {
// $val[0] is the full matched list-item line
// $val[1] is the level (number)
// $val[2] is the type (* or #)
// $val[3] is the list item text
// how many levels are we indented? (1 means the "root"
// list level, no indenting.)
$stars = $val[1];
$level = strlen($stars);
$last = $stars[strlen($stars) - 1];
// get the list item type
if ($last == '*' || $last == '-') {
$type = 'bullet';
} elseif ($last == '#') {
$type = 'number';
} else {
$type = 'unknown';
}
// get the text of the list item
$text = $val[3];
// remove a level from the list?
while (count($stack) > $level || (count($stack) == $level && $type != $stack[$level - 1])) {
// so we don't keep counting the stack, we set up a temp
// var for the count. -1 becuase we're going to pop the
// stack in the next command. $tmp will then equal the
// current level of indent.
$tmp = count($stack) - 1;
// as long as the stack count is greater than the
// current indent level, we need to end list types.
// continue adding end-list tokens until the stack count
// and the indent level are the same.
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => array_pop($stack) . '_list_end',
'level' => $tmp
)
);
// reset to the current (previous) list type so that
// the new list item matches the proper list type.
if ($tmp) {
$oldtype = $stack[$tmp - 1];
}
// reset the item count for the popped indent level
unset($itemcount[$tmp + 1]);
}
// add a level to the list?
if ($level > count($stack)) {
// the current indent level is greater than the
// number of stack elements, so we must be starting
// a new list. push the new list type onto the
// stack...
array_push($stack, $type);
// ...and add a list-start token to the return.
$return .= $this->wiki->addToken(
$this->rule,
array(
'type' => $type . '_list_start',
'level' => $level - 1
)
);
}
// add to the item count for this list (taking into account
// which level we are at).
if (! isset($itemcount[$level])) {
// first count
$itemcount[$level] = 0;
} else {
// increment count
$itemcount[$level]++;
}
// is this the very first item in the list?
if (! $pastFirst) {
$first = true;
$pastFirst = true;
} else {
$first = false;
}
// create a list-item starting token.
$start = $this->wiki->addToken(
$this->rule,
array(
'type' => $type . '_item_start',
'level' => $level,
'count' => $itemcount[$level],
'first' => $first
)
);
// create a list-item ending token.
$end = $this->wiki->addToken(
$this->rule,
array(
'type' => $type . '_item_end',
'level' => $level,
'count' => $itemcount[$level]
)
);
// add the starting token, list-item text, and ending token
// to the return.
$return .= "\n" . $start . $text . $end;
}
// the last list-item may have been indented. go through the
// list-type stack and create end-list tokens until the stack
// is empty.
while (count($stack) > 0) {
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => array_pop($stack) . '_list_end',
'level' => count($stack)
)
);
}
// we're done! send back the replacement text.
return "\n\n" . $return . "\n\n";
}
}
?>
-60
View File
@@ -1,60 +0,0 @@
<?php
/**
*
* Parses for implied line breaks indicated by newlines.
* Newlines are not considered if followed by another newline
* or by one of these chars: * | - # = {
*
* @category Text
*
* @package Text_Wiki
*
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Newline.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Newline extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = '/(?<!\n)\n(?![\n\#\=\|\-\>\:]|\*[^\*\#]|\*+ )/m';
var $regex = '/(?<!\n)\n(?!\n|\#|\*|\=|\||\>|\:|\!|\-\D)/m';
/**
*
* Generates a replacement token for the matched text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A delimited token to be used as a placeholder in
* the source text.
*
*/
function process(&$matches)
{
return ' '; // $this->wiki->addToken($this->rule);
}
}
?>
-139
View File
@@ -1,139 +0,0 @@
<?php
/**
*
* Parses for paragraph blocks.
* This class implements a Text_Wiki rule to find sections of the source
* text that are paragraphs. A paragraph is any line not starting with a
* token delimiter, followed by two newlines.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Paragraph.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Paragraph extends Text_Wiki_Parse {
/**
*
* The regular expression used to find source text matching this
* rule.
*
* @access public
*
* @var string
*
*/
var $regex = "/^.+?\n/m"; // (?=[\n\-\|#{=])
var $conf = array(
'skip' => array(
'address',
'box',
'blockquote',
'code',
'heading',
'center',
'horiz',
'deflist',
'table',
'list',
'paragraph',
'preformatted',
'toc'
)
);
/**
*
* Generates a token entry for the matched text. Token options are:
*
* 'start' => The starting point of the paragraph.
*
* 'end' => The ending point of the paragraph.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A delimited token number to be used as a placeholder in
* the source text.
*
*/
function process(&$matches)
{
$delim = $this->wiki->delim;
// was anything there?
if (trim($matches[0]) == '') {
return '';
}
// does the match start with a delimiter?
if (substr($matches[0], 0, 1) != $delim) {
// no.
$start = $this->wiki->addToken(
$this->rule, array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule, array('type' => 'end')
);
return $start . trim($matches[0]) . $end;
}
// the line starts with a delimiter. read in the delimited
// token number, check the token, and see if we should
// skip it.
// loop starting at the second character (we already know
// the first is a delimiter) until we find another
// delimiter; the text between them is a token key number.
$key = '';
$len = strlen($matches[0]);
for ($i = 1; $i < $len; $i++) {
$char = $matches[0]{$i};
if ($char == $delim) {
break;
} else {
$key .= $char;
}
}
// look at the token and see if it's skippable (if we skip,
// it will not be marked as a paragraph)
$token_type = strtolower($this->wiki->tokens[$key][0]);
$skip = $this->getConf('skip', array());
if (in_array($token_type, $skip)) {
// this type of token should not have paragraphs applied to it.
// return the entire matched text.
return $matches[0];
} else {
$start = $this->wiki->addToken(
$this->rule, array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule, array('type' => 'end')
);
return $start . trim($matches[0]) . $end;
}
}
}
?>
-54
View File
@@ -1,54 +0,0 @@
<?php
/**
*
* "Pre-filter" the source text.
*
* Convert DOS and Mac line endings to Unix, convert tabs to 4-spaces,
* add newlines to the top and end of the source text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Prefilter.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Prefilter extends Text_Wiki_Parse {
/**
*
* Simple parsing method.
*
* @access public
*
*/
function parse()
{
// convert DOS line endings
$this->wiki->source = str_replace("\r\n", "\n",
$this->wiki->source);
// convert Macintosh line endings
$this->wiki->source = str_replace("\r", "\n",
$this->wiki->source);
// convert tabs to four-spaces
$this->wiki->source = str_replace("\t", " ",
$this->wiki->source);
// add extra newlines at the top and end; this
// seems to help many rules.
$this->wiki->source = "\n\n" . $this->wiki->source . "\n\n";
}
}
?>
-68
View File
@@ -1,68 +0,0 @@
<?php
/**
*
* Parses for preformatted text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Preformatted.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Preformatted extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/\n{{{\n(.*)\n}}}\n/Us';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'text' => The preformatted text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token to be used as a placeholder
* in the source text for the preformatted text.
*
*/
function process(&$matches)
{
// > any line consisting of only indented three closing curly braces
// > will have one space removed from the indentation
// > -- http://www.wikicreole.org/wiki/AddNoWikiEscapeProposal
$find = "/\n( *) }}}/";
$replace = "\n$1}}}";
$matches[1] = preg_replace($find, $replace, $matches[1]);
$token = $this->wiki->addToken(
$this->rule,
array('text' => $matches[1])
);
return "\n\n" . $token . "\n\n";
}
}
?>
-61
View File
@@ -1,61 +0,0 @@
<?php
/**
*
* Parses for monospaced inline text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Raw.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Raw extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/~~([^ \n])/';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* monospaced text. The text itself is encapsulated into a Raw token.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token to be used as a placeholder
* in the source text for the preformatted text.
*
*/
function process(&$matches)
{
return $this->wiki->addToken(
$this->rule,
array('text' => $matches[1], 'type' => 'escape')
);
}
}
?>
-83
View File
@@ -1,83 +0,0 @@
<?php
/**
*
* Parses for bold text.
*
* This class implements a Text_Wiki_Rule to find source text marked for
* strong emphasis (bold) as defined by text surrounded by two
* stars. On parsing, the text itself is left in place, but the
* starting and ending instances of two stars are replaced with
* tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Strong.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Strong extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = "/\*\*(.*?)\*\*/";
var $regex = "/(?:\*\*(.+?)\*\*|(?:(?<=[\W_\xFF])\*(?![ \*]))(.+?)(?:(?<![ \*])\*(?=[\W_\xFF])))/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* emphasized text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A pair of delimited tokens to be used as a placeholder in
* the source text surrounding the text to be emphasized.
*
*/
function process(&$matches)
{
$text = $matches[1] ? $matches[1] : $matches[2];
if (! $this->wiki->checkInnerTags($text)) {
return $matches[0];
}
$start = $this->wiki->addToken(
$this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule,
array('type' => 'end')
);
return $start . $text . $end;
}
}
?>
-75
View File
@@ -1,75 +0,0 @@
<?php
/**
*
* Parses for italic text.
*
* This class implements a Text_Wiki_Parse to find source text marked for
* superscript as defined by text surrounded by two '^'.
* On parsing, the text itself is left in place, but the starting and ending
* instances of two '^' are replaced with tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Subscript extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = "/\,\,(.*?)\,\,/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* superscript text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the text to be
* superscripted.
*
*/
function process(&$matches)
{
if (! $this->wiki->checkInnerTags($matches[1])) {
return $matches[0];
}
$start = $this->wiki->addToken(
$this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule,
array('type' => 'end')
);
return $start . $matches[1] . $end;
}
}
?>
-75
View File
@@ -1,75 +0,0 @@
<?php
/**
*
* Parses for italic text.
*
* This class implements a Text_Wiki_Parse to find source text marked for
* superscript as defined by text surrounded by two '^'.
* On parsing, the text itself is left in place, but the starting and ending
* instances of two '^' are replaced with tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Superscript extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = "/\^\^(.*?)\^\^/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* superscript text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the text to be
* superscripted.
*
*/
function process(&$matches)
{
if (! $this->wiki->checkInnerTags($matches[1])) {
return $matches[0];
}
$start = $this->wiki->addToken(
$this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule,
array('type' => 'end')
);
return $start . $matches[1] . $end;
}
}
?>
-207
View File
@@ -1,207 +0,0 @@
<?php
/**
*
* Parses for table markup.
*
* This class implements a Text_Wiki_Parse to find source text marked as
* a set of table rows, where a line start (and optionally ends) with a
* single-pipe (|) and uses single-pipes to separate table cells.
* The rows must be on sequential lines (no blank lines between them).
* A blank line indicates the beginning of other text or another table.
*
* @category Text
*
* @package Text_Wiki
*
* @author Michele Tomaiuolo <tomamic@yahoo.it>
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Table.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Table extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/\n((\|).*)(\n)(?!(\|))/Us';
/**
*
* Generates a replacement for the matched text.
*
* Token options are:
*
* 'type' =>
* 'table_start' : the start of a bullet list
* 'table_end' : the end of a bullet list
* 'row_start' : the start of a number list
* 'row_end' : the end of a number list
* 'cell_start' : the start of item text (bullet or number)
* 'cell_end' : the end of item text (bullet or number)
*
* 'cols' => the number of columns in the table (for 'table_start')
*
* 'rows' => the number of rows in the table (for 'table_start')
*
* 'span' => column span (for 'cell_start')
*
* 'attr' => column attribute flag (for 'cell_start')
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A series of text and delimited tokens marking the different
* table elements and cell text.
*
*/
function process(&$matches)
{
// our eventual return value
$return = '';
// the number of columns in the table
$num_cols = 0;
// the number of rows in the table
$num_rows = 0;
// rows are separated by newlines in the matched text
$rows = explode("\n", $matches[1]);
// loop through each row
foreach ($rows as $row) {
// increase the row count
$num_rows ++;
// remove first and last (optional) pipe
$row = substr($row, 1);
if ($row[strlen($row) - 1] == '|') {
$row = substr($row, 0, -1);
}
// cells are separated by pipes
$cells = explode("|", $row);
if (count($cells) == 1 && $cells[0][0] == '=' && ($num_rows == 1 || $num_rows == count($rows)) && ! $caption) {
$caption = trim(trim($cells[0], '='));
// start the caption...
$return .= $this->wiki->addToken(
$this->rule,
array ('type' => 'caption_start')
);
// ...add the content...
$return .= $caption;
// ...and end the caption.
$return .= $this->wiki->addToken(
$this->rule,
array ('type' => 'caption_end')
);
}
else {
// update the column count
if (count($cells) > $num_cols) {
$num_cols = count($cells);
}
// start a new row
$return .= $this->wiki->addToken(
$this->rule,
array('type' => 'row_start')
);
for ($i = 0; $i < count($cells); $i++) {
$cell = $cells[$i];
// by default, cells span only one column (their own)
$span = 1;
$attr = '';
while ($i + 1 < count($cells) && ! strlen($cells[$i + 1])) {
$i++;
$span++;
}
if ($cell[0] == '=') {
$attr = 'header';
$cell = trim($cell, '=');
}
// start a new cell...
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => 'cell_start',
'attr' => $attr,
'span' => $span
)
);
// ...add the content...
$return .= trim($cell);
// ...and end the cell.
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => 'cell_end',
'attr' => $attr,
'span' => $span
)
);
}
// end the row
$return .= $this->wiki->addToken(
$this->rule,
array('type' => 'row_end')
);
}
}
// we're done!
return
"\n\n".
$this->wiki->addToken(
$this->rule,
array(
'type' => 'table_start',
'rows' => $num_rows,
'cols' => $num_cols
)
).
$return.
$this->wiki->addToken(
$this->rule,
array(
'type' => 'table_end'
)
).
"\n\n";
}
}
?>
-37
View File
@@ -1,37 +0,0 @@
<?php
/**
*
* The rule removes all remaining newlines.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Tighten.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Tighten extends Text_Wiki_Parse {
/**
*
* Apply tightening directly to the source text.
*
* @access public
*
*/
function parse()
{
$this->wiki->source = str_replace("\n", '',
$this->wiki->source);
}
}
?>
-69
View File
@@ -1,69 +0,0 @@
<?php
/**
*
* Trim lines in the source text and compress 3 or more newlines to
* 2 newlines.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Trim extends Text_Wiki_Parse {
/**
*
* Simple parsing method.
*
* @access public
*
*/
function parse()
{
// trim lines
$find = "/ *\n */";
$replace = "\n";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// trim lines with only one dash or star
$find = "/\n[\-\*]\n/";
$replace = "\n\n";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// finally, compress all instances of 3 or more newlines
// down to two newlines.
$find = "/\n{3,}/m";
$replace = "\n\n";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// numbered lists
$find = "/(\n[\*\#]*)([\d]+[\.\)]|[\w]\))/s";
$replace = "$1#";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// make ordinal numbers superscripted
$find = "/([\d])(st|nd|rd|th|er|e|re|ers|res|nds|de|des|ère|ème|ères|èmes|o|a)([\W])/";
$replace = "$1^^$2^^$3";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// numbers in parentesis are footnotes and references
$find = "/\(([\d][\d]?)\)/";
$replace = "[$1]";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// add hr before footnotes
$find = "/(\n+\-\-\-\-+\n*)?(\n\[[\d]+\].*)/s";
$replace = "\n\n----\n\n$2";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
}
}
?>
-78
View File
@@ -1,78 +0,0 @@
<?php
/**
*
* Parses for monospaced inline text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Tt.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Tt extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/{{{(.*?)}}}(?!}|{{{)/';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* monospaced text. The text itself is encapsulated into a Raw token.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token to be used as a placeholder
* in the source text for the preformatted text.
*
*/
function process(&$matches)
{
// remove the sequence }}}{{{
$find = "/}}}{{{/";
$replace = "";
$matches[1] = preg_replace($find, $replace, $matches[1]);
$start = $this->wiki->addToken(
$this->rule,
array('type' => 'start')
);
$raw = $this->wiki->addToken(
'Raw',
array('text' => $matches[1])
);
$end = $this->wiki->addToken(
$this->rule,
array('type' => 'end')
);
return $start . $raw . $end;
}
}
?>
-78
View File
@@ -1,78 +0,0 @@
<?php
/**
*
* Parses for italic text.
*
* This class implements a Text_Wiki_Parse to find source text marked for
* underlined as defined by text surrounded by two '_'.
* On parsing, the text itself is left in place, but the starting and ending
* instances of two '^' are replaced with tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Underline extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = "/__(.*?)__/";
var $regex = "/(?:\_\_(.+?)\_\_|(?:(?<=[\W_\xFF])\_(?![ \_]))(.+?)(?:(?<![ \_])\_(?=[\W_\xFF])))/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* superscript text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the text to be
* superscripted.
*
*/
function process(&$matches)
{
$text = $matches[1] ? $matches[1] : $matches[2];
if (! $this->wiki->checkInnerTags($text)) {
return $matches[0];
}
$start = $this->wiki->addToken(
'Underline', // $this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
'Underline', // $this->rule,
array('type' => 'end')
);
return $start . $text . $end;
}
}
?>
-109
View File
@@ -1,109 +0,0 @@
<?php
/**
*
* Parse for URLS in the source text.
*
* raw -- http://example.com
* no descr. -- [[http://example.com]]
* described -- [[http://example.com|Example Description]]
*
* When rendering a URL token, this will convert URLs pointing to a .gif,
* .jpg, or .png image into an inline <img /> tag (for the 'xhtml'
* format).
*
* @category Text
*
* @package Text_Wiki
*
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Url.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Url extends Text_Wiki_Parse {
/**
*
* Constructor. Overrides the Text_Wiki_Parse constructor so that we
* can set the $regex property dynamically (we need to include the
* Text_Wiki $delim character).
*
* @param object &$obj The calling "parent" Text_Wiki object.
*
* @param string $name The token name to use for this rule.
*
*/
function Text_Wiki_Parse_Url(&$obj)
{
parent::Text_Wiki_Parse($obj);
$this->regex = '/((?:\[\[ *((?:http:\/\/|https:\/\/|ftp:\/\/|mailto:|\/)[^\|\]\n ]*)( *\| *([^\]\n]*))? *\]\])|((http:\/\/|https:\/\/|ftp:\/\/|mailto:)[^\'\"\n ' . $this->wiki->delim . ']*[A-Za-z0-9\/\?\=\&\~\_]))/';
}
/**
*
* Generates a replacement for the matched text.
*
* Token options are:
*
* 'href' => the URL link href portion
*
* 'text' => the displayed text of the URL link
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token to be used as a placeholder
* in the source text for the preformatted text.
*
*/
function process(&$matches)
{
if (isset($matches[2])) $href = trim($matches[2]);
if (isset($matches[4])) $text = trim($matches[4]);
if (isset($matches[5])) $rawurl = $matches[5];
if (empty($href)) $href = $rawurl;
if (empty($text)) {
$text = $href;
if (strpos($text, '/') === FALSE) {
$text = str_replace('http://', '', $text);
$text = str_replace('mailto:', '', $text);
}
return $this->wiki->addToken(
$this->rule,
array(
'type' => 'inline',
'href' => $href,
'text' => $text
)
);
} else {
return $this->wiki->addToken(
$this->rule,
array(
'type' => 'start',
'href' => $href,
'text' => $text
)
) . $text .
$this->wiki->addToken(
$this->rule,
array(
'type' => 'end',
'href' => $href,
'text' => $text
)
);
}
}
}
?>
-72
View File
@@ -1,72 +0,0 @@
<?php
/**
* 使用 <a href="http://www.wikicreole.org/" target="_blank">Creole 语法</a>发布文章。改进版本支持中文(utf-8 编码)、并除去不必要的标签。
*
* @package Creole 解析器(改进版)
* @author 明城<i.feelinglucky@gmail.com>
* @version 0.2
* @link http://www.gracecode.com/
*/
require_once 'Creole/Creole_Wiki.php';
class Creole_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate() {
Typecho_Plugin::factory('Widget_Abstract_Contents')->excerpt = array('Creole_Plugin', 'parse');
Typecho_Plugin::factory('Widget_Abstract_Contents')->content = array('Creole_Plugin', 'parse');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate() {
}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
/**
* 插件实现方法
*
* @access public
* @return void
*/
public static function parse($text, $widget, $lastResult) {
$text = empty($lastResult) ? $text : $lastResult;
$creole_parse = new Creole_Wiki;
return $creole_parse->transform(trim($text));
}
}
-218
View File
@@ -1,218 +0,0 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Base rendering class for parsed and tokenized text.
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Render.inc.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* Base rendering class for parsed and tokenized text.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render {
/**
*
* Configuration options for this render rule.
*
* @access public
*
* @var string
*
*/
var $conf = array();
/**
*
* The name of this rule's format.
*
* @access public
*
* @var string
*
*/
var $format = null;
/**
*
* The name of this rule's token array elements.
*
* @access public
*
* @var string
*
*/
var $rule = null;
/**
*
* A reference to the calling Text_Wiki object.
*
* This is needed so that each rule has access to the same source
* text, token set, URLs, interwiki maps, page names, etc.
*
* @access public
*
* @var object
*/
var $wiki = null;
/**
*
* Constructor for this render format or rule.
*
* @access public
*
* @param object &$obj The calling "parent" Text_Wiki object.
*
*/
function Text_Wiki_Render(&$obj)
{
// keep a reference to the calling Text_Wiki object
$this->wiki =& $obj;
// get the config-key-name for this object,
// strip the Text_Wiki_Render_ part
// 01234567890123456
$tmp = get_class($this);
$tmp = substr($tmp, 17);
// split into pieces at the _ mark.
// first part is format, second part is rule.
$part = explode('_', $tmp);
$this->format = isset($part[0]) ? ucwords(strtolower($part[0])) : null;
$this->rule = isset($part[1]) ? ucwords(strtolower($part[1])) : null;
// is there a format but no rule?
// then this is the "main" render object, with
// pre() and post() methods.
if ($this->format && ! $this->rule &&
isset($this->wiki->formatConf[$this->format]) &&
is_array($this->wiki->formatConf[$this->format])) {
// this is a format render object
$this->conf = array_merge(
$this->conf,
$this->wiki->formatConf[$this->format]
);
}
// is there a format and a rule?
if ($this->format && $this->rule &&
isset($this->wiki->renderConf[$this->format][$this->rule]) &&
is_array($this->wiki->renderConf[$this->format][$this->rule])) {
// this is a rule render object
$this->conf = array_merge(
$this->conf,
$this->wiki->renderConf[$this->format][$this->rule]
);
}
}
/**
*
* Simple method to safely get configuration key values.
*
* @access public
*
* @param string $key The configuration key.
*
* @param mixed $default If the key does not exist, return this value
* instead.
*
* @return mixed The configuration key value (if it exists) or the
* default value (if not).
*
*/
function getConf($key, $default = null)
{
if (isset($this->conf[$key])) {
return $this->conf[$key];
} else {
return $default;
}
}
/**
*
* Simple method to wrap a configuration in an sprintf() format.
*
* @access public
*
* @param string $key The configuration key.
*
* @param string $format The sprintf() format string.
*
* @return mixed The formatted configuration key value (if it exists)
* or null (if it does not).
*
*/
function formatConf($format, $key)
{
if (isset($this->conf[$key])) {
//$this->conf[$key] needs a textEncode....at least for Xhtml output...
return sprintf($format, $this->conf[$key]);
} else {
return null;
}
}
/**
* Default method to render url
*
* @access public
* @param string $urlChunk a part of an url to render
* @return rendered url
*
*/
function urlEncode($urlChunk)
{
return rawurlencode($urlChunk);
}
/**
* Default method to render text (htmlspecialchars)
*
* @access public
* @param string $text the text to render
* @return rendered text
*
*/
function textEncode($text)
{
return htmlspecialchars($text);
}
}
?>
-16
View File
@@ -1,16 +0,0 @@
<?php
class Text_Wiki_Render_Plain extends Text_Wiki_Render {
function pre()
{
return;
}
function post()
{
return;
}
}
?>
@@ -1,23 +0,0 @@
<?php
/**
*
* This class renders an anchor target name in XHTML.
*
* @author Manuel Holtgrewe <purestorm at ggnore dot net>
*
* @author Paul M. Jones <pmjones at ciaweb dot net>
*
* @package Text_Wiki
*
*/
class Text_Wiki_Render_Plain_Anchor extends Text_Wiki_Render {
function token($options)
{
return $options['name'];
}
}
?>
@@ -1,39 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Blockquote extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
$type = $options['type'];
$level = $options['level'];
// set up indenting so that the results look nice; we do this
// in two steps to avoid str_pad mathematics. ;-)
$pad = str_pad('', $level + 1, "\t");
$pad = str_replace("\t", ' ', $pad);
// starting
if ($type == 'start') {
return "\n$pad";
}
// ending
if ($type == 'end') {
return "\n$pad";
}
}
}
?>
-23
View File
@@ -1,23 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Bold extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>
-48
View File
@@ -1,48 +0,0 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Box rule end renderer for Plain
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Box.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders a box drawn in Plain.
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Plain_Box extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return '';
}
}
?>
-24
View File
@@ -1,24 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Break extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return "\n";
}
}
?>
@@ -1,23 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Center extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>
-24
View File
@@ -1,24 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Code extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return "\n" . $options['text'] . "\n\n";
}
}
?>
@@ -1,23 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Colortext extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>
@@ -1,59 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Deflist extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
$type = $options['type'];
$pad = " ";
switch ($type) {
case 'list_start':
return "\n";
break;
case 'list_end':
return "\n\n";
break;
case 'term_start':
// done!
return $pad;
break;
case 'term_end':
return "\n";
break;
case 'narr_start':
// done!
return $pad . $pad;
break;
case 'narr_end':
return "\n";
break;
default:
return '';
}
}
}
?>
@@ -1,23 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Delete extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>
@@ -1,23 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Delimiter extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>
-23
View File
@@ -1,23 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Embed extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return strip_tags($options['text']);
}
}
?>
@@ -1,23 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Emphasis extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>
-44
View File
@@ -1,44 +0,0 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* BBCode: extra Font rules renderer to size the text
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Font.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* Font rule render class (used for BBCode)
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
* @see Text_Wiki::Text_Wiki_Render()
*/
class Text_Wiki_Render_Plain_Font extends Text_Wiki_Render {
/**
* Renders a token into text matching the requested format.
* process the font size option
*
* @access public
* @param array $options The "options" portion of the token (second element).
* @return string The text rendered from the token options.
*/
function token($options)
{
return;
}
}
?>
@@ -1,23 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Freelink extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return $options['text'];
}
}
?>
@@ -1,39 +0,0 @@
<?php
// $Id: Function.php 182 2008-09-14 15:56:00Z i.feelinglucky $
class Text_Wiki_Render_Plain_Function extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
extract($options); // access, return, name, params, throws
$output = "$access $return $name ( ";
foreach ($params as $key => $val) {
$output .= "{$val['type']} {$val['descr']} {$val['default']} ";
}
$output .= ') ';
foreach ($throws as $key => $val) {
$output .= "{$val['type']} {$val['descr']} ";
}
return $output;
}
}
?>
@@ -1,14 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Heading extends Text_Wiki_Render {
function token($options)
{
if ($options['type'] == 'end') {
return "\n\n";
} else {
return "\n";
}
}
}
?>
-23
View File
@@ -1,23 +0,0 @@
<?php
class Text_Wiki_Render_Plain_Horiz extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return "\n";
}
}
?>

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