赵鹏 6 years ago
commit c5cd2b64b1

@ -40,7 +40,7 @@
</div>
<div class="modal-body">
<label>需要更新的URL</label>
<input type="text" class="form-control" name="cdn_url" id="cdn_url" placeholder="如https://data.chinarundreisen.com/min/?f=/css/tailorbox.css" />
<input type="text" class="form-control" name="cdn_url" id="cdn_url" placeholder="如https://data.chinarundreisen.com/min/?f=/css/tailorbox.css" style="width:98%"/>
<input type="hidden" name="updatecdn_byhand" id="updatecdn_byhand" value="">
<p class="text-danger" id="cdncache_refresh_modal_msg" name="cdncache_refresh_modal_msg"></p>

@ -881,11 +881,15 @@ class Index extends CI_Controller {
$orderid_info = json_decode($orderid_info);
// 仅自动程序发送提醒 false == $handpick &&
if (strtolower($item->pn_payment_status) === 'completed'
&& $orderid_info->ordertype == 'A' && strpos($get_order_no, 'China Train Booking') !== false) {
&& $orderid_info->ordertype == 'A'
) {
// APP 组的China Train Booking-开头的订单号
// 发送邮件提醒外联核对收款金额, 不写入收款记录
$if_empty_gai = $this->process_notify_APP($item, $orderid_info);
if($if_empty_gai !== true) { continue; } // 收款记录为空, 需要补录
if($if_empty_gai !== true) {
$this->Note_model->update_send($item->pn_txn_id, 'send', $item->pn_sn);
continue;
} // 收款记录为空, 需要补录
}
//检测是否是APP订单,默认不处理

@ -1388,6 +1388,7 @@ class TulanduoApi extends CI_Controller
return array(
"故宫深度一日游(目的地)" => "BJSIC-44"
,"故宫深度游拼团(目的地)" => "BJSIC-44"
,"故宫深度半日游(目的地)" => "BJSIC-44"
,"北京精品一日游(目的地)" => "BJSIC-41"
,"北京精品一日游PVT目的地" => "BJSIC-41"
,"北京精品两日游(目的地)" => "BJSIC-42"

@ -179,6 +179,7 @@ class Order_finance extends CI_Controller {
$report_tour_pvt['RPT_Other'] = $cpvt->cost_category['otherCosts'];
$report_tour_pvt['RPT_Total'] = $cpvt->cost_sum;
$report_tour_pvt['RPT_PersonGrade'] = $cpvt->person_grade;
$report_tour_pvt['this_coldsn'] = implode(',', $cpvt->cold_sn);
$ret->report_tour[] = $report_tour_pvt;
// 计算订单总成本
$report_order['basemoney'] = bcadd($report_order['basemoney'], $report_tour_pvt['tourcost']);
@ -220,6 +221,7 @@ class Order_finance extends CI_Controller {
$cost_c['RPT_Other'] = $cost->cost_category['otherCosts'];
$cost_c['RPT_Total'] = $cost->cost_sum;
$cost_c['RPT_PersonGrade'] = $cost->person_num;
$cost_c['this_coldsn'] = implode(',', array_map(function ($ele){return $ele->COLD_SN;}, $cost->order_cost));
$ret->report_tour[] = $cost_c;
// 计算订单总成本
$report_order['basemoney'] = bcadd($report_order['basemoney'], $cost_c['tourcost']);

@ -116,7 +116,9 @@ class Vendor_money extends CI_Controller {
"transfer_sum" => 0,
"other_sum_cost" => 0,
"other_sum" => 0,
"other_vendor_sum" => 0
"other_vendor_sum" => 0,
"trippest_cost" => 0,
"vendor_cost" => 0
)
);
foreach ($final_table as $line => $row) {
@ -136,13 +138,26 @@ class Vendor_money extends CI_Controller {
if ($sync['vendor_code'] != $vendor ) {
continue;
}
if (in_array($sync['GCI_combineNo'],$unique_sync_groupno)) {
$dumplicate_groupno[] = $sync;
continue;
}
$unique_sync_groupno[] = $sync['GCI_combineNo'];
$ret['sync']['price_sum'] = bcadd($ret['sync']['price_sum'], $sync['receive_price']);
$ret['sync']['cost_sum'] = bcadd($ret['sync']['cost_sum'], $sync['cost']);
$ret['sync']['trippest_sum'] = bcadd($ret['sync']['trippest_sum'], $sync['SyncHainaReceipt']);
$ret['sync']['vendor_sum'] = bcadd($ret['sync']['vendor_sum'], $sync['SyncAgencyReceipt']);
$ret['sync']['vendor_cost'] = bcadd($ret['sync']['vendor_cost'], $sync['SyncCombineCost']);
/** 利润 */
$ret['sync']['total_profit'] = bcsub(
bcadd($ret['sync']['trippest_sum'], $ret['sync']['vendor_sum']),
$ret['sync']['vendor_cost']);
/** 利润分成 */
$ret['sync']['vendor_profit'] = bcmul($ret['sync']['total_profit'], $vendor_sourcetype[strval($sync['vendor_code'])]["profit_rate"]);
$ret['sync']['trippest_profit'] = bcmul($ret['sync']['total_profit'], bcsub(1, $vendor_sourcetype[strval($sync['vendor_code'])]["profit_rate"]) );
/** Trippest应付地接 */
$ret['sync']['payout'] = bcsub(bcadd($ret['sync']['vendor_cost'], $ret['sync']['vendor_profit'] ), $ret['sync']['vendor_sum']);
// if (in_array($sync['GCI_combineNo'],$unique_sync_groupno)) {
// $dumplicate_groupno[] = $sync;
// continue;
// }
// $unique_sync_groupno[] = $sync['GCI_combineNo'];
// $ret['sync']['price_sum'] = bcadd($ret['sync']['price_sum'], $sync['receive_price']);
// $ret['sync']['cost_sum'] = bcadd($ret['sync']['cost_sum'], $sync['cost']);
}
$result["money"][strval($vendor)] = $ret;
$result["money"][strval($vendor)]["vendor_code"] = $vendor;
@ -154,8 +169,11 @@ class Vendor_money extends CI_Controller {
$result['col_sum']['trippest']['sum_vendor_sum'] = bcadd($result['col_sum']['trippest']['sum_vendor_sum'], $ret["trippest"]['vendor_sum']);
$result['col_sum']['trippest']['sum_other'] = bcadd($result['col_sum']['trippest']['sum_other'], $ret['trippest']['other_sum']);
$result['col_sum']['sync']['sum_price_sum'] = bcadd($result['col_sum']['sync']['sum_price_sum'], $ret["sync"]['price_sum']);
$result['col_sum']['sync']['sum_cost_sum'] = bcadd($result['col_sum']['sync']['sum_cost_sum'], $ret["sync"]['cost_sum']);
$result['col_sum']['sync']['sum_trippest_sum'] = bcadd($result['col_sum']['sync']['sum_trippest_sum'], $ret['sync']['trippest_sum']);
$result['col_sum']['sync']['sum_vendor_sum'] = bcadd($result['col_sum']['sync']['sum_vendor_sum'], $ret["sync"]['vendor_sum']);
$result['col_sum']['sync']['sum_price_sum'] = bcadd($result['col_sum']['sync']['sum_price_sum'],
bcadd($ret['sync']['trippest_sum'], $ret["sync"]['vendor_sum']));
$result['col_sum']['sync']['sum_cost_sum'] = bcadd($result['col_sum']['sync']['sum_cost_sum'], $ret["sync"]['vendor_cost']);
// 成本总计
$result['col_sum']['trippest']['sum_trippest_cost'] = $result['col_sum']['vendor']['sum_trippest_cost'] = bcadd($result['col_sum']['trippest']['sum_trippest_cost'], $ret['trippest_cost']);
$result['col_sum']['trippest']['sum_vendor_cost'] = $result['col_sum']['vendor']['sum_vendor_cost'] = bcadd(
@ -179,8 +197,13 @@ class Vendor_money extends CI_Controller {
$result['col_sum']['trippest']['sum_trippest_profit'] = bcadd($result['col_sum']['trippest']['sum_trippest_profit'], $vmi['trippest']['trippest_profit']);
$result['col_sum']['trippest']['sum_vendor_profit'] = bcadd($result['col_sum']['trippest']['sum_vendor_profit'], $vmi['trippest']['vendor_profit']);
$result['col_sum']['sync']['sum_profit'] = bcadd($result['col_sum']['sync']['sum_profit'], $vmi['sync']['total_profit']);
$result['col_sum']['sync']['sum_trippest_profit'] = bcadd($result['col_sum']['sync']['sum_trippest_profit'], $vmi['sync']['trippest_profit']);
$result['col_sum']['sync']['sum_vendor_profit'] = bcadd($result['col_sum']['sync']['sum_vendor_profit'], $vmi['sync']['vendor_profit']);
/** 应付总计 */
$result['col_sum']['trippest']['sum_payout'] = bcadd($result['col_sum']['trippest']['sum_payout'], $vmi['trippest']['payout']);
$result['col_sum']['sync']['sum_payout'] = bcadd($result['col_sum']['sync']['sum_payout'], $vmi['sync']['payout']);
}
// 财务表成本和实际成本不相等
$result['diff_cost'] = $this->money_model->report_tour_diff($start_date, $end_date, implode(',', $vendors));

@ -270,19 +270,19 @@ class OrderFinance_model extends CI_Model {
{
foreach ($report_tour_arr as $krt => $vrt) {
$tourBz_tmp = "";
if ($this->report_tour_exists($vrt['ordernumber'], $vrt['RPT_COLD_SN']) === TRUE) {
$where = " ordernumber='" . $vrt['ordernumber'] . "' and RPT_COLD_SN=".$vrt['RPT_COLD_SN'] ; //AND tourCode='" . $vrt['tourCode'] . "' ";
$tourBz_tmp = mb_ereg_replace('[^a-zA-Z0-9\-\[\]]$', '', strstr($vrt['tourBZ'], ",", true));
if (stripos($tourBz_tmp, "pvt") === false) {
$tourBz_tmp = str_replace("]", "", $tourBz_tmp);
}
$tourBz_tmp = str_replace("[", "[[]", $tourBz_tmp);
$tourBz_tmp = mb_ereg_replace('[^a-zA-Z0-9\-\[\]]$', '', strstr($vrt['tourBZ'], ",", true));
if (stripos($tourBz_tmp, "pvt") === false) {
$tourBz_tmp = str_replace("]", "", $tourBz_tmp);
}
$tourBz_tmp = str_replace("[", "[[]", $tourBz_tmp);
$where = " ordernumber='" . $vrt['ordernumber'] . "' and RPT_COLD_SN IN (" . $vrt['this_coldsn'] . ") " ;
$where .= " AND (tourBZ like '%" . $this->HT->escape_like_str($tourBz_tmp) . "%'
OR tourBZ='') ";
OR tourBZ=''
OR orderstats=0
) ";
$delete_sql = "DELETE FROM tourmanager.dbo.Report_Tour where " . $where;
// $update_sql = $this->HT->update_string('tourmanager.dbo.Report_Tour', $vrt, $where);
$this->HT->query($delete_sql);
}
unset($vrt['this_coldsn']);
$this->HT->insert('tourmanager.dbo.Report_Tour', $vrt);
}
return TRUE;

@ -492,38 +492,46 @@ class Vendor_money_model extends CI_Model {
public function get_sync_price_cost($start_date, $end_date, $all_vendor)
{
$sql = "SELECT group_cost.GCI_VEI_SN vendor_code,
GCI_combineNo,
(SELECT isnull(SUM(CONVERT(float, isnull(gcod.GCOD_sumMoney,0))),0)
FROM GroupCombineOperationDetail gcod
WHERE gcod.GCOD_GCI_combineNo=GCI_combineNo
AND gcod.GCOD_operationType<> 'otherReceives'
) AS cost
,(select SUM(CONVERT(float, GCI_priceCNY)) from GroupCombineInfo where GCI_combineNo=group_cost.GCI_combineNo
) as receive_price
,(select SUM(CONVERT(float, GCI_agencyReceipt)) from GroupCombineInfo where GCI_combineNo=group_cost.GCI_combineNo
) as agency_receive_price
FROM
(SELECT case when gci.GCI_combineNo is null then '1'
when gci.GCI_combineNo='cancel' then convert(varchar(10),gci.GCI_SN)
else gci.GCI_combineNo end
as GCI_combineNo
,GCI_VEI_SN
FROM GroupCombineInfo gci
WHERE 1=1
AND GCI_VEI_SN IN ($all_vendor)
AND EXISTS
( SELECT 1
FROM CK_GroupInfo
WHERE CGI_Checked=1
AND CGI_GRI_SN=GCI_GRI_SN
AND CGI_ArriveDate BETWEEN '$start_date' AND '$end_date')
group by case when gci.GCI_combineNo is null then '1'
when gci.GCI_combineNo='cancel' then convert(varchar(10),gci.GCI_SN)
else gci.GCI_combineNo end
,GCI_VEI_SN
) AS group_cost
order by GCI_combineNo desc";
$sql = "SELECT
SUM(combine.SyncHainaReceipt) as SyncHainaReceipt,
SUM(combine.SyncAgencyReceipt) as SyncAgencyReceipt,
SUM(combine.SyncCombineCost) as SyncCombineCost,
combine.GCI_VEI_SN as vendor_code
from (
select
SUM(gri_coli.SyncPrice) as SyncPrice,
SUM(gri_coli.SyncAgencyReceipt) as SyncAgencyReceipt,
SUM(gri_coli.SyncHainaReceipt) as SyncHainaReceipt,
(select SUM(CONVERT(decimal(10,2), gcod.GCOD_sumMoney)) total_cost
from GroupCombineOperationDetail gcod
where gcod.GCOD_GCI_combineNo=gri_coli.GCI_combineNo and gcod.GCOD_VEI_SN=gri_coli.GCI_VEI_SN
) as SyncCombineCost,
gri_coli.GCI_combineNo,
gri_coli.GCI_VEI_SN
from (
select
convert(decimal(10,2),isnull(gci.GCI_priceCNY,0)) as SyncPrice,
case when COLI_OPI_ID=435 then CONVERT(decimal(10,2),isnull(gci.GCI_priceCNY,0))
else convert(decimal(10,2),isnull(gci.GCI_agencyReceipt,0)) end
as SyncAgencyReceipt,
case when COLI_OPI_ID=435 then 0
else (convert(decimal(10,2),isnull(gci.GCI_priceCNY,0))-convert(decimal(10,2),isnull(gci.GCI_agencyReceipt,0))) end
as SyncHainaReceipt,
GCI_createTime as lastSynsTime,
GCI_combineNo,
GCI_VEI_SN
from GroupCombineInfo gci
inner join BIZ_ConfirmLineInfo coli on COLI_GRI_SN=GCI_GRI_SN
where
GCI_travelDate between '$start_date' and '$end_date'
and COLI_State<>50
and isnull(GCI_combineNo,'') not in ('','cancel','forbidden')
) as gri_coli
group by GCI_combineNo,
GCI_VEI_SN
) as combine
group by combine.GCI_VEI_SN
order by vendor_code";
$query = $this->HT->query($sql);
return $query->result_array();
}

@ -273,20 +273,21 @@
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>目的地</th>
<th>总营收:①海纳代收+②地接代收</th>
<th>总成本:③海纳成本+④地接成本</th>
<th>⑤利润</th>
<th>⑥海纳利润</th>
<th>⑦地接利润</th>
<th>⑧海纳应付地接</th>
<th rowspan="2">目的地</th>
<th colspan="3">总营收</th>
<th colspan="2">总成本</th>
<th rowspan="2">⑤利润</th>
<th rowspan="2">⑥海纳利润</th>
<th rowspan="2">⑦地接利润</th>
<th rowspan="2">⑧海纳应付地接</th>
</tr>
<tr>
<th>①海纳代收</th>
<th>②地接代收</th>
<th>①+②</th>
<th>③海纳成本</th>
<th>④地接成本</th>
</tr>
<!-- <tr>
<th >①海纳代收</th>
<th >②地接代收</th>
<th rowspan="2">③海纳成本</th>
<th rowspan="2">④地接成本</th>
</tr> -->
</thead>
<tbody>
<?php if (!empty($money)) {
@ -294,18 +295,15 @@
?>
<tr>
<td class="text-left"><?php echo $sync['vendor_name'] ?></td>
<!-- <td><?php //echo $sync['sync']['trippest_sum']
?></td> -->
<td><?php echo $sync['sync']['price_sum'] ?></td>
<td><?php echo $sync['sync']['cost_sum'] ?></td>
<td><?php // echo $sync['vendor_cost']
?></td>
<td><?php // echo $sync['sync']['total_profit']
?></td>
<td><?php // echo $sync['sync']['trippest_profit']
?></td>
<td><?php // echo $sync['sync']['vendor_profit']
?></td>
<td><?php echo $sync['sync']['trippest_sum'] ?></td>
<td><?php echo $sync['sync']['vendor_sum'] ?></td>
<td><?php echo bcadd($sync['sync']['trippest_sum'], $sync['sync']['vendor_sum']) ?></td>
<td><?php echo $sync['sync']['trippest_cost'] ?></td>
<td><?php echo $sync['sync']['vendor_cost'] ?></td>
<td><?php echo $sync['sync']['total_profit'] ?></td>
<td><?php echo $sync['sync']['trippest_profit'] ?></td>
<td><?php echo $sync['sync']['vendor_profit'] ?></td>
<td><?php echo $sync['sync']['payout'] ?></td>
</tr>
<?php }
} ?>
@ -313,18 +311,21 @@
?>
<tr class="text-bold">
<td class="text-left">合计</td>
<!-- <td><?php //echo $col_sum['sync']['sum_trippest_sum']
?></td> -->
<td><?php echo $col_sum['sync']['sum_price_sum'] ?></td>
<td><?php echo $col_sum['sync']['sum_cost_sum'] ?></td>
<td><?php // echo $col_sum['sync']['sum_vendor_cost']
<td><?php echo $col_sum['sync']['sum_trippest_sum']
?></td>
<td><?php echo $col_sum['sync']['sum_vendor_sum'] ?></td>
<td><?php echo $col_sum['sync']['sum_price_sum']
?></td>
<td><?php // echo $col_sum['sync']['sum_profit']
<td></td>
<td><?php echo $col_sum['sync']['sum_cost_sum']
?></td>
<td><?php // echo $col_sum['sync']['sum_trippest_profit']
<td><?php echo $col_sum['sync']['sum_profit']
?></td>
<td><?php // echo $col_sum['sync']['sum_vendor_profit']
<td><?php echo $col_sum['sync']['sum_trippest_profit']
?></td>
<td><?php echo $col_sum['sync']['sum_vendor_profit']
?></td>
<td><?php echo $col_sum['sync']['sum_payout'] ?></td>
</tr>
<?php } ?>
</tbody>
@ -339,15 +340,33 @@
<p class="text-center"> 实际总成本</p>
</th>
<th class="text-left">
<p class="text-center"> 财务表总成本</p>
<p class="text-center"> 财务表读取总成本</p>
<ol class="info-primary">
<li> 数据为空: 虚拟订单没有团号, 无法计算. 如:
<ul>
<li> TA导游奖励计入成本的虚拟订单. 人工检查金额正确之后, 此处可忽略该团. </li>
<li> 团号修改后无法匹配. </li>
<li> HT Trippest小组不存在该产品, 可能在Day Trip中或其他小组下, Trippest中应是产品最全的. </li>
</ul>
</li>
<li> 数据不为空:
<ul>
<li> HT自动生成账单后, 地接再次修改了成本数据, HT不会再次自动生成. 目前HT自动生成账单的时间策略是 每月初生成上上个月的团. 比如20191201自动生成201910月份的账单. </li>
<li> 拼团号下的个别订单, 由于同时预订了其他产品已经提前审核账单, 账单中的图兰朵产品未更新成本数据, 对已审核的账单, 自动账单程序会跳过, 不覆盖数据. </li>
</ul>
</li>
</ol>
</th>
<th class="text-left">
<p class="text-center"> 财务表计算总成本</p>
<!-- <ol class="info-primary">
<li> 数据为空: 虚拟订单没有团号, 无法计算. 如:
<ul>
<li> TA导游奖励计入成本的虚拟订单. 人工检查金额正确之后, 此处可忽略该团. </li>
</ul>
</li>
</ol> -->
</th>
</tr>
</thead>
<tbody>
@ -356,6 +375,7 @@
<td><?php echo $diff['gci_no'] ?></td>
<td><?php echo $diff['total_cost'] ?></td>
<td><?php echo $diff['report_total_cost0'] ?></td>
<td><?php echo $diff['report_cost'] ?></td>
</tr>
<?php } ?>
</tbody>

@ -47,7 +47,7 @@ CKEDITOR.editorConfig = function( config ) {
config.extraPlugins= 'tableresize,uploadimage,image2,codemirror,hianamedia,textselection';
config.extraPlugins= 'tableresize,uploadimage,image2,codemirror,hianamedia,textselection,wordcount';
config.codemirror = {
showFormatButton: false,
showCommentButton: false,

@ -0,0 +1,3 @@
.cke_wordcount {display:block;float:right;margin-top:-2px;margin-right:3px;color:black;}
.cke_wordcountLimitReached {color:red! important}

@ -0,0 +1,12 @@
// Arabic Translation by Amine BENHAMIDA
CKEDITOR.plugins.setLang('wordcount', 'ar', {
WordCount: 'كلمات:',
CharCount: 'حروف:',
CharCountWithHTML: 'حروف مع إتش تي إم إل',
Paragraphs: 'فقرات',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'لا يمكن اضافة هذا المحتوى لانه تجاوز الحد الاقصى',
Selected: 'محدد: ',
title: 'احصائيات'
});

@ -0,0 +1,17 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'bg', {
WordCount: 'Думи:',
WordCountRemaining: 'Оставащи думи',
CharCount: 'Знаци:',
CharCountRemaining: 'Знаци',
CharCountWithHTML: 'Знаци (с HTML):',
CharCountWithHTMLRemaining: 'Оставащи знаци (с HTML)',
Paragraphs: 'Параграфи:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Съдържанието не може да бъде поставено, защото е над разрешения лимит',
Selected: 'Избрани: ',
title: 'Статистика'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'ca', {
WordCount: 'Paraules:',
CharCount: 'Caràcters:',
CharCountWithHTML: 'Caràcters (including HTML):',
Paragraphs: 'Paragraphs:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Content can not be pasted because it is above the allowed limit',
Selected: 'Selected: ',
title: 'Estadístiques'
});

@ -0,0 +1,15 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'cs',
{
WordCount: 'Slov: ',
CharCount: 'Znaků: ',
CharCountWithHTML: 'Znaků (s HTML): ',
Paragraphs: 'Odstavců: ',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Obsah nelze vložit',
Selected: 'Výběr: ',
title: 'Statistika'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'da', {
WordCount: 'Ord:',
CharCount: 'Karakterer:',
CharCountWithHTML: 'Karakterer (med HTML):',
Paragraphs: 'Afsnit:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Indholdet kan ikke indsættes da det er længere end den tilladte grænse.',
Selected: 'Markeret: ',
title: 'Statistik'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'de', {
WordCount: 'Wörter:',
CharCount: 'Zeichen:',
CharCountWithHTML: 'Zeichen (inkl. HTML):',
Paragraphs: 'Absätze:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Content can not be pasted because it is above the allowed limit',
Selected: 'Selected: ',
title: 'Statistik'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'el', {
WordCount: 'Λέξεις:',
CharCount: 'Χαρακτήρες:',
CharCountWithHTML: 'Χαρακτήρες (μαζί με HTML):',
Paragraphs: 'Paragraphs:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Content can not be pasted because it is above the allowed limit',
Selected: 'Selected: ',
title: 'Στατιστικά'
});

@ -0,0 +1,17 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'en', {
WordCount: 'Words:',
WordCountRemaining: 'Words remaining',
CharCount: 'Characters:',
CharCountRemaining: 'Characters remaining',
CharCountWithHTML: 'Characters (with HTML):',
CharCountWithHTMLRemaining: 'Characters (with HTML) remaining',
Paragraphs: 'Paragraphs:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Content cannot be pasted because it is above the allowed limit',
Selected: 'Selected: ',
title: 'Statistics'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'es', {
WordCount: 'Palabras:',
CharCount: 'Carácteres:',
CharCountWithHTML: 'Carácteres (con HTML):',
Paragraphs: 'Párrafos:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'El contenido no se puede pegar, ya que se encuentra fuera del límite permitido',
Selected: 'Seleccionado: ',
title: 'Estadísticas'
});

@ -0,0 +1,17 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'eu', {
WordCount: 'Hitzak:',
WordCountRemaining: 'Gelditzen diren hitzak',
CharCount: 'Karaktereak:',
CharCountRemaining: 'Gelditzen diren karaktereak',
CharCountWithHTML: 'Karaktereak (HTMLarekin):',
CharCountWithHTMLRemaining: 'Gelditzen diren karaktereak (HTMLarekin)',
Paragraphs: 'Paragrafoak:',
ParagraphsRemaining: 'Gelditzen diren paragrafoak',
pasteWarning: 'Ezin da edukia itsatsi, onartutako muga gainditu duelako',
Selected: 'Hautatuta: ',
title: 'Estatistikak'
});

@ -0,0 +1,13 @@
/*
Its The Persian (Farsi) Language Translate For Iranian By "Mohsen Esmaili"
*/
CKEDITOR.plugins.setLang('wordcount', 'fa', {
WordCount: 'لغت:',
CharCount: 'کاراکتر:',
CharCountWithHTML: 'کاراکترها (با HTML):',
Paragraphs: 'پاراگراف:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'محتوای مورد نظر را نمی توان چسباند. زیرا این بیشتر از حد مجاز است.',
Selected: 'انتخاب شده: ',
title: 'آمار'
});

@ -0,0 +1,15 @@
/**
* Finnish localisation.
*
* @author Joel Posti / Response200.pro
*/
CKEDITOR.plugins.setLang('wordcount', 'fi', {
WordCount: 'Sanoja:',
CharCount: 'Merkkejä:',
CharCountWithHTML: 'Merkkejä (ml. HTML):',
Paragraphs: 'Kappaleita:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Sisältöä ei voida liittää, koska se ylittää sallitun rajan.',
Selected: 'Valittuna: ',
title: 'Statistiikkaa'
});

@ -0,0 +1,12 @@
// French Translation by Nicolas M. et Pierre-Luc Auclair
CKEDITOR.plugins.setLang('wordcount', 'fr', {
WordCount: 'Mots :',
CharCount: 'Caractères :',
CharCountWithHTML: 'Caractères (incluant HTML) :',
Paragraphs: 'Paragraphes :',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Le contenu ne peut pas être collé car il dépasse la limite autorisée',
Selected: 'Sélectionné :',
title: 'Statistiques'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'he', {
WordCount: 'מילים:',
CharCount: 'תווים:',
CharCountWithHTML: 'תווים (כולל HTML):',
Paragraphs: 'פסקאות:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'לא ניתן להדביק תוכן בשל עודף תווים',
Selected: 'נבחר: ',
title: 'סטטיסטיקות'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'hr', {
WordCount: 'Riječi:',
CharCount: 'Znakova:',
CharCountWithHTML: 'Znakova (uključujući HTML):',
Paragraphs: 'Paragraphs:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Content can not be pasted because it is above the allowed limit',
Selected: 'Selected: ',
title: 'Statistika'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'hu', {
WordCount: 'Szavak:',
CharCount: 'Karakaterek:',
CharCountWithHTML: 'Karakterek (HTML tagekkel):',
Paragraphs: 'Bekezdések:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'A szöveget nem lehet beilleszteni, mert a megadott limit felett van',
Selected: 'Kiválasztva: ',
title: 'Statisztika'
});

@ -0,0 +1,15 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
@author translation: Davide Montorio
*/
CKEDITOR.plugins.setLang('wordcount', 'it', {
WordCount: 'Parole:',
CharCount: 'Caratteri:',
CharCountWithHTML: 'Caratteri (HTML incluso):',
Paragraphs: 'Paragrafi:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Il contenuto non può essere incollato poiché supera il limite massimo di caratteri disponibili',
Selected: 'Selezionato: ',
title: 'Statistiche'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'ja', {
WordCount: '単語数:',
CharCount: '文字数:',
CharCountWithHTML: '文字数 (HTMLタグを含む):',
Paragraphs: '段落数:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: '文字数/単語数の上限を超えるため、貼り付けできません。',
Selected: '選択中の字数:',
title: 'ワードカウント'
});

@ -0,0 +1,16 @@
/*
Korean translation by Maxime Houdais
*/
CKEDITOR.plugins.setLang('wordcount', 'ko', {
WordCount: '단어:',
WordCountRemaining: '남은 단어',
CharCount: '글자:',
CharCountRemaining: '남은 글자',
CharCountWithHTML: '글자 와 HTML:',
CharCountWithHTMLRemaining: '남은 글자 와 HTML',
Paragraphs: '단락:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: '허용 된 한도를 초과하여 콘텐츠를 붙여 넣을 수 없습니다.',
Selected: '선택:',
title: '통계'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'nl', {
WordCount: 'Woorden:',
CharCount: 'Tekens:',
CharCountWithHTML: 'Tekens (inclusief HTML):',
Paragraphs: 'Paragrafen:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'De tekst kan niet worden geplakt omdat de limiet is overschreden',
Selected: 'Geselecteerd: ',
title: 'Statistieken'
});

@ -0,0 +1,11 @@
// Norwegian translation by Vegard S.
CKEDITOR.plugins.setLang('wordcount', 'no', {
WordCount: 'Ord:',
CharCount: 'Tegn:',
CharCountWithHTML: 'Tegn (including HTML):',
Paragraphs: 'Paragraphs:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Content can not be pasted because it is above the allowed limit',
Selected: 'Selected: ',
title: 'Statistikk'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'pl', {
WordCount: 'Słów:',
CharCount: 'Znaków:',
CharCountWithHTML: 'Znaków (wraz z kodem HTML):',
Paragraphs: 'Paragrafy:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Zawartość nie może zostać wklejona, ponieważ przekracza dozwolony limit',
Selected: 'Zaznaczono: ',
title: 'Statystyka'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'pt-br', {
WordCount: 'Contagem de palavras:',
CharCount: 'Contagem de carateres:',
CharCountWithHTML: 'Carateres (incluindo HTML):',
Paragraphs: 'Parágrafos:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Conteúdo não pode ser colado porque ultrapassa o limite permitido',
Selected: 'Selecionado: ',
title: 'Estatísticas'
});

@ -0,0 +1,10 @@
CKEDITOR.plugins.setLang('wordcount', 'pt', {
WordCount: 'Palavras:',
CharCount: 'Caracteres:',
CharCountWithHTML: 'Carateres (incluindo HTML):',
Paragraphs: 'Parágrafos:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'O conteúdo não pode ser colado porque ultrapassa o limite permitido',
Selected: 'Selecionado: ',
title: 'Estatísticas'
});

@ -0,0 +1,15 @@
// Romanian Translation by Bogdanov Mihail
CKEDITOR.plugins.setLang('wordcount', 'ro', {
WordCount: 'Numar cuvinte',
WordCountRemaining: 'Cuvinte ramase',
CharCount: 'Numar caracter:',
CharCountRemaining: 'Caractere ramase:',
CharCountWithHTML: 'Numar caractere (cu HTML):',
CharCountWithHTMLRemaining: 'Caractere (cu HTML) ramase',
Paragraphs: 'Paragrafe:',
ParagraphsRemaining: 'Paragrafe ramase',
pasteWarning: 'Continutul nu poate fi adaugat deoarece este mai mare decat limita setata',
Selected: 'Selectat:',
title: 'Statistici'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'ru', {
WordCount: 'Слов:',
CharCount: 'Символов:',
CharCountWithHTML: ' (включая HTML-разметку):',
Paragraphs: 'Параграфов:',
ParagraphsRemaining: 'Параграфов осталось',
pasteWarning: 'Контент не может быть вставлен, т.к. привышает допустимый лимит',
Selected: 'Выделено: ',
title: 'Статистика'
});

@ -0,0 +1,15 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'sk', {
WordCount: 'Slov:',
CharCount: 'Znakov:',
CharCountWithHTML: 'Znakov (vrátane HTML):',
Paragraphs: 'Odstavcov:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Obsah sa nedá prilepiť.',
Selected: 'Výber: ',
title: 'Štatistika'
});

@ -0,0 +1,15 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'sv', {
WordCount: 'Ord:',
CharCount: 'Tecken:',
CharCountRemaining: 'tecken återstår',
CharCountWithHTML: 'Tecken (inklusive HTML):',
Paragraphs: 'Paragraf:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Innehåll kan inte klistras in eftersom det överskrider den tillåtna gränsen',
Selected: 'Valt: ',
title: 'Statistik'
});

@ -0,0 +1,14 @@
/*
Mesut ÇAKIR
mesut.cakir@hotmail.com.tr
*/
CKEDITOR.plugins.setLang('wordcount', 'tr', {
WordCount: 'Kelime:',
CharCount: 'Karakter:',
CharCountWithHTML: 'Karakter (HTML dahil):',
Paragraphs: 'Paragraf:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: 'Content can not be pasted because it is above the allowed limit',
Selected: 'Selected: ',
title: 'İstatistik'
});

@ -0,0 +1,17 @@
/*
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'uk', {
WordCount: 'Слів:',
WordCountRemaining: 'Слів залишилося',
CharCount: 'Символів:',
CharCountRemaining: 'Символів залишилося',
CharCountWithHTML: 'Символів (включаючи HTML-розмітку):',
CharCountWithHTMLRemaining: 'Символів (включаючи HTML-розмітку) залишилося',
Paragraphs: 'Параграфів:',
ParagraphsRemaining: 'Параграфів залишилося',
pasteWarning: 'Контент не може бути вставлено, оскільки перевищує допустимий ліміт',
Selected: 'Виділено: ',
title: 'Статистика'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'zh-cn', {
WordCount: '词数:',
CharCount: '字符:',
CharCountWithHTML: '字符 (含HTML)',
Paragraphs: '段落:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: '由于上限允许,内容不能粘贴',
Selected: '已选择: ',
title: '统计'
});

@ -0,0 +1,14 @@
/*
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang('wordcount', 'zh', {
WordCount: '詞數:',
CharCount: '字數:',
CharCountWithHTML: '字數 (含HTML)',
Paragraphs: '段落:',
ParagraphsRemaining: 'Paragraphs remaining',
pasteWarning: '由於字數達到上限,內容不能粘貼',
Selected: '已選擇: ',
title: '統計'
});

@ -0,0 +1,596 @@
/**
* @license Copyright (c) CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.html or http://ckeditor.com/license
*/
CKEDITOR.plugins.add("wordcount",
{
lang: "ar,bg,ca,cs,da,de,el,en,es,eu,fa,fi,fr,he,hr,hu,it,ko,ja,nl,no,pl,pt,pt-br,ru,sk,sv,tr,uk,zh-cn,zh,ro", // %REMOVE_LINE_CORE%
version: "1.17.6",
requires: 'htmlwriter,notification,undo',
bbcodePluginLoaded: false,
onLoad: function() {
CKEDITOR.document.appendStyleSheet(this.path + "css/wordcount.css");
},
init: function(editor) {
var defaultFormat = "",
lastWordCount = -1,
lastCharCount = -1,
lastParagraphs = -1,
limitReachedNotified = false,
limitRestoredNotified = false,
timeoutId = 0,
notification = null;
var dispatchEvent = function(type, currentLength, maxLength) {
if (typeof document.dispatchEvent == 'undefined') {
return;
}
type = 'ckeditor.wordcount.' + type;
var cEvent;
var eventInitDict = {
bubbles: false,
cancelable: true,
detail: {
currentLength: currentLength,
maxLength: maxLength
}
};
try {
cEvent = new CustomEvent(type, eventInitDict);
} catch (o_O) {
cEvent = document.createEvent('CustomEvent');
cEvent.initCustomEvent(
type,
eventInitDict.bubbles,
eventInitDict.cancelable,
eventInitDict.detail
);
}
document.dispatchEvent(cEvent);
};
// Default Config
var defaultConfig = {
showRemaining: false,
showParagraphs: true,
showWordCount: true,
showCharCount: false,
countBytesAsChars: false,
countSpacesAsChars: false,
countHTML: false,
countLineBreaks: false,
hardLimit: true,
warnOnLimitOnly: false,
//MAXLENGTH Properties
maxWordCount: -1,
maxCharCount: -1,
maxParagraphs: -1,
// Filter
filter: null,
// How long to show the 'paste' warning
pasteWarningDuration: 0,
//DisAllowed functions
wordCountGreaterThanMaxLengthEvent: function(currentLength, maxLength) {
dispatchEvent('wordCountGreaterThanMaxLengthEvent', currentLength, maxLength);
},
charCountGreaterThanMaxLengthEvent: function(currentLength, maxLength) {
dispatchEvent('charCountGreaterThanMaxLengthEvent', currentLength, maxLength);
},
//Allowed Functions
wordCountLessThanMaxLengthEvent: function(currentLength, maxLength) {
dispatchEvent('wordCountLessThanMaxLengthEvent', currentLength, maxLength);
},
charCountLessThanMaxLengthEvent: function(currentLength, maxLength) {
dispatchEvent('charCountLessThanMaxLengthEvent', currentLength, maxLength);
}
};
// Get Config & Lang
var config = CKEDITOR.tools.extend(defaultConfig, editor.config.wordcount || {}, true);
if (config.showParagraphs) {
if (config.maxParagraphs > -1) {
if (config.showRemaining) {
defaultFormat += "%paragraphsCount% " + editor.lang.wordcount.ParagraphsRemaining;
} else {
defaultFormat += editor.lang.wordcount.Paragraphs + " %paragraphsCount%";
defaultFormat += "/" + config.maxParagraphs;
}
} else {
defaultFormat += editor.lang.wordcount.Paragraphs + " %paragraphsCount%";
}
}
if (config.showParagraphs && (config.showWordCount || config.showCharCount)) {
defaultFormat += ", ";
}
if (config.showWordCount) {
if (config.maxWordCount > -1) {
if (config.showRemaining) {
defaultFormat += "%wordCount% " + editor.lang.wordcount.WordCountRemaining;
} else {
defaultFormat += editor.lang.wordcount.WordCount + " %wordCount%";
defaultFormat += "/" + config.maxWordCount;
}
} else {
defaultFormat += editor.lang.wordcount.WordCount + " %wordCount%";
}
}
if (config.showCharCount && config.showWordCount) {
defaultFormat += ", ";
}
if (config.showCharCount) {
if (config.maxCharCount > -1) {
if (config.showRemaining) {
defaultFormat += "%charCount% " +
editor.lang.wordcount[config.countHTML
? "CharCountWithHTMLRemaining"
: "CharCountRemaining"];
} else {
defaultFormat += editor.lang.wordcount[config.countHTML
? "CharCountWithHTML"
: "CharCount"] +
" %charCount%";
defaultFormat += "/" + config.maxCharCount;
}
} else {
defaultFormat += editor.lang.wordcount[config.countHTML ? "CharCountWithHTML" : "CharCount"] +
" %charCount%";
}
}
var format = defaultFormat;
bbcodePluginLoaded = typeof editor.plugins.bbcode != 'undefined';
function counterId(editorInstance) {
return "cke_wordcount_" + editorInstance.name;
}
function counterElement(editorInstance) {
return document.getElementById(counterId(editorInstance));
}
function strip(html) {
if (bbcodePluginLoaded) {
// stripping out BBCode tags [...][/...]
return html.replace(/\[.*?\]/gi, '');
}
var tmp = document.createElement("div");
// Add filter before strip
html = filter(html);
tmp.innerHTML = html;
if (tmp.textContent == "" && typeof tmp.innerText == "undefined") {
return "";
}
return tmp.textContent || tmp.innerText;
}
/**
* Implement filter to add or remove before counting
* @param html
* @returns string
*/
function filter(html) {
if (config.filter instanceof CKEDITOR.htmlParser.filter) {
var fragment = CKEDITOR.htmlParser.fragment.fromHtml(html),
writer = new CKEDITOR.htmlParser.basicWriter();
config.filter.applyTo(fragment);
fragment.writeHtml(writer);
return writer.getHtml();
}
return html;
}
function countCharacters(text) {
if (config.countHTML) {
return config.countBytesAsChars ? countBytes(filter(text)) : filter(text).length;
}
var normalizedText;
// strip body tags
if (editor.config.fullPage) {
var i = text.search(new RegExp("<body>", "i"));
if (i != -1) {
var j = text.search(new RegExp("</body>", "i"));
text = text.substring(i + 6, j);
}
}
normalizedText = text;
if (!config.countSpacesAsChars) {
normalizedText = text.replace(/\s/g, "").replace(/&nbsp;/g, "");
}
if (config.countLineBreaks) {
normalizedText = normalizedText.replace(/(\r\n|\n|\r)/gm, " ");
} else {
normalizedText = normalizedText.replace(/(\r\n|\n|\r)/gm, "").replace(/&nbsp;/gi, " ");
}
normalizedText = strip(normalizedText).replace(/^([\t\r\n]*)$/, "");
return config.countBytesAsChars ? countBytes(normalizedText) : normalizedText.length;
}
function countBytes(text) {
var count = 0, stringLength = text.length, i;
text = String(text || "");
for (i = 0; i < stringLength; i++) {
var partCount = encodeURI(text[i]).split("%").length;
count += partCount == 1 ? 1 : partCount - 1;
}
return count;
}
function countParagraphs(text) {
return (text.replace(/&nbsp;/g, " ").replace(/(<([^>]+)>)/ig, "").replace(/^\s*$[\n\r]{1,}/gm, "++")
.split("++").length);
}
function countWords(text) {
var normalizedText = text.replace(/(\r\n|\n|\r)/gm, " ").replace(/^\s+|\s+$/g, "")
.replace("&nbsp;", " ");
normalizedText = strip(normalizedText);
var words = normalizedText.split(/\s+/);
for (var wordIndex = words.length - 1; wordIndex >= 0; wordIndex--) {
if (words[wordIndex].match(/^([\s\t\r\n]*)$/)) {
words.splice(wordIndex, 1);
}
}
return (words.length);
}
function limitReached(editorInstance, notify) {
limitReachedNotified = true;
limitRestoredNotified = false;
if (!config.warnOnLimitOnly) {
if (config.hardLimit) {
editorInstance.execCommand('undo');
}
}
if (!notify) {
counterElement(editorInstance).className = "cke_path_item cke_wordcountLimitReached";
editorInstance.fire("limitReached", { firedBy: "wordCount.limitReached" }, editor);
}
}
function limitRestored(editorInstance) {
limitRestoredNotified = true;
limitReachedNotified = false;
if (!config.warnOnLimitOnly) {
editorInstance.fire('saveSnapshot');
}
counterElement(editorInstance).className = "cke_path_item";
}
function updateCounter(editorInstance) {
if (!counterElement(editorInstance)) {
return;
}
var paragraphs = 0,
wordCount = 0,
charCount = 0,
text;
// BeforeGetData and getData events are fired when calling
// getData(). We can prevent this by passing true as an
// argument to getData(). This allows us to fire the events
// manually with additional event data: firedBy. This additional
// data helps differentiate calls to getData() made by
// wordCount plugin from calls made by other plugins/code.
editorInstance.fire("beforeGetData", { firedBy: "wordCount.updateCounter" }, editor);
text = editorInstance.getData(true);
editorInstance.fire("getData", { dataValue: text, firedBy: "wordCount.updateCounter" }, editor);
if (text) {
if (config.showCharCount) {
charCount = countCharacters(text);
}
if (config.showParagraphs) {
paragraphs = countParagraphs(text);
}
if (config.showWordCount) {
wordCount = countWords(text);
}
}
var html = format;
if (config.showRemaining) {
if (config.maxCharCount >= 0) {
html = html.replace("%charCount%", config.maxCharCount - charCount);
} else {
html = html.replace("%charCount%", charCount);
}
if (config.maxWordCount >= 0) {
html = html.replace("%wordCount%", config.maxWordCount - wordCount);
} else {
html = html.replace("%wordCount%", wordCount);
}
if (config.maxParagraphs >= 0) {
html = html.replace("%paragraphsCount%", config.maxParagraphs - paragraphs);
} else {
html = html.replace("%paragraphsCount%", paragraphs);
}
} else {
html = html.replace("%wordCount%", wordCount).replace("%charCount%", charCount).replace("%paragraphsCount%", paragraphs);
}
(editorInstance.config.wordcount || (editorInstance.config.wordcount = {})).wordCount = wordCount;
(editorInstance.config.wordcount || (editorInstance.config.wordcount = {})).charCount = charCount;
if (CKEDITOR.env.gecko) {
counterElement(editorInstance).innerHTML = html;
} else {
counterElement(editorInstance).innerText = html;
}
if (charCount == lastCharCount && wordCount == lastWordCount && paragraphs == lastParagraphs) {
if (charCount == config.maxCharCount || wordCount == config.maxWordCount || paragraphs > config.maxParagraphs) {
editorInstance.fire('saveSnapshot');
}
return true;
}
//If the limit is already over, allow the deletion of characters/words. Otherwise,
//the user would have to delete at one go the number of offending characters
var deltaWord = wordCount - lastWordCount;
var deltaChar = charCount - lastCharCount;
var deltaParagraphs = paragraphs - lastParagraphs;
lastWordCount = wordCount;
lastCharCount = charCount;
lastParagraphs = paragraphs;
if (lastWordCount == -1) {
lastWordCount = wordCount;
}
if (lastCharCount == -1) {
lastCharCount = charCount;
}
if (lastParagraphs == -1) {
lastParagraphs = paragraphs;
}
// Check for word limit and/or char limit
if ((config.maxWordCount > -1 && wordCount > config.maxWordCount && deltaWord > 0) ||
(config.maxCharCount > -1 && charCount > config.maxCharCount && deltaChar > 0) ||
(config.maxParagraphs > -1 && paragraphs > config.maxParagraphs && deltaParagraphs > 0)) {
limitReached(editorInstance, limitReachedNotified);
} else if ((config.maxWordCount == -1 || wordCount <= config.maxWordCount) &&
(config.maxCharCount == -1 || charCount <= config.maxCharCount) &&
(config.maxParagraphs == -1 || paragraphs <= config.maxParagraphs)) {
limitRestored(editorInstance);
} else {
editorInstance.fire('saveSnapshot');
}
// update instance
editorInstance.wordCount =
{
paragraphs: paragraphs,
wordCount: wordCount,
charCount: charCount
};
// Fire Custom Events
if (config.charCountGreaterThanMaxLengthEvent && config.charCountLessThanMaxLengthEvent) {
if (charCount > config.maxCharCount && config.maxCharCount > -1) {
config.charCountGreaterThanMaxLengthEvent(charCount, config.maxCharCount);
} else {
config.charCountLessThanMaxLengthEvent(charCount, config.maxCharCount);
}
}
if (config.wordCountGreaterThanMaxLengthEvent && config.wordCountLessThanMaxLengthEvent) {
if (wordCount > config.maxWordCount && config.maxWordCount > -1) {
config.wordCountGreaterThanMaxLengthEvent(wordCount, config.maxWordCount);
} else {
config.wordCountLessThanMaxLengthEvent(wordCount, config.maxWordCount);
}
}
return true;
}
function isCloseToLimits() {
if (config.maxWordCount > -1 && config.maxWordCount - lastWordCount < 5) {
return true;
}
if (config.maxCharCount > -1 && config.maxCharCount - lastCharCount < 20) {
return true;
}
if (config.maxParagraphs > -1 && config.maxParagraphs - lastParagraphs < 1) {
return true;
}
return false;
}
editor.on("key",
function(event) {
if (editor.mode === "source") {
clearTimeout(timeoutId);
timeoutId = setTimeout(
updateCounter.bind(this, event.editor),
250
);
}
},
editor,
null,
100);
editor.on("change",
function(event) {
var ms = isCloseToLimits() ? 5 : 250;
clearTimeout(timeoutId);
timeoutId = setTimeout(
updateCounter.bind(this, event.editor),
ms
);
},
editor,
null,
100);
editor.on("uiSpace",
function(event) {
if (editor.elementMode === CKEDITOR.ELEMENT_MODE_INLINE) {
if (event.data.space == "top") {
event.data.html += "<div class=\"cke_wordcount\" style=\"\"" +
" title=\"" +
editor.lang.wordcount.title +
"\"" +
"><span id=\"" +
counterId(event.editor) +
"\" class=\"cke_path_item\">&nbsp;</span></div>";
}
} else {
if (event.data.space == "bottom") {
event.data.html += "<div class=\"cke_wordcount\" style=\"\"" +
" title=\"" +
editor.lang.wordcount.title +
"\"" +
"><span id=\"" +
counterId(event.editor) +
"\" class=\"cke_path_item\">&nbsp;</span></div>";
}
}
},
editor,
null,
100);
editor.on("dataReady",
function(event) {
updateCounter(event.editor);
},
editor,
null,
100);
editor.on("paste",
function(event) {
if (!config.warnOnLimitOnly && (config.maxWordCount > 0 || config.maxCharCount > 0 || config.maxParagraphs > 0)) {
// Check if pasted content is above the limits
var wordCount = -1,
charCount = -1,
paragraphs = -1;
// BeforeGetData and getData events are fired when calling
// getData(). We can prevent this by passing true as an
// argument to getData(). This allows us to fire the events
// manually with additional event data: firedBy. This additional
// data helps differentiate calls to getData() made by
// wordCount plugin from calls made by other plugins/code.
event.editor.fire("beforeGetData", { firedBy: "wordCount.onPaste" }, event.editor);
var text = event.editor.getData(true);
event.editor.fire("getData", { dataValue: text, firedBy: "wordCount.onPaste" }, event.editor);
text += event.data.dataValue;
if (config.showCharCount) {
charCount = countCharacters(text);
}
if (config.showWordCount) {
wordCount = countWords(text);
}
if (config.showParagraphs) {
paragraphs = countParagraphs(text);
}
// Instantiate the notification when needed and only have one instance
if (notification === null) {
notification = new CKEDITOR.plugins.notification(event.editor,
{
message: event.editor.lang.wordcount.pasteWarning,
type: 'warning',
duration: config.pasteWarningDuration
});
}
if (config.maxCharCount > 0 && charCount > config.maxCharCount && config.hardLimit) {
if (!notification.isVisible()) {
notification.show();
}
event.cancel();
}
if (config.maxWordCount > 0 && wordCount > config.maxWordCount && config.hardLimit) {
if (!notification.isVisible()) {
notification.show();
}
event.cancel();
}
if (config.maxParagraphs > 0 && paragraphs > config.maxParagraphs && config.hardLimit) {
if (!notification.isVisible()) {
notification.show();
}
event.cancel();
}
}
},
editor,
null,
100);
editor.on("afterPaste",
function(event) {
updateCounter(event.editor);
},
editor,
null,
100);
}
});

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CKEditor</title>
<script src="../../../ckeditor.js"></script>
</head>
<body>
<textarea name="editor1"></textarea>
<script>
var config = {
extraPlugins: 'wordcount',
wordcount: {
maxParagraphs: 5,
showParagraphs: true,
showWordCount: false,
showRemaining: true
},
language: 'en'
}
</script>
<script>
CKEDITOR.replace( 'editor1' , config);
</script>
</body>
</html>

@ -0,0 +1,61 @@
<!DOCTYPE html>
<!--
Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
-->
<html>
<head>
<meta charset="utf-8">
<title>WordCount &mdash; CKEditor Sample</title>
<script src="../../../ckeditor.js"></script>
<link href="../../../samples/sample.css" rel="stylesheet">
<meta name="ckeditor-sample-name" content="WordCount plugin">
<meta name="ckeditor-sample-group" content="Plugins">
<meta name="ckeditor-sample-description" content="Counts the words an shows the word count in the footer of the editor.">
<meta name="ckeditor-sample-isnew" content="1">
<script>
CKEDITOR.disableAutoInline = true;
</script>
</head>
<body>
<h1 class="samples">
<a href="../../../samples/index.html">CKEditor Samples</a> &raquo; WordCount Plugin
</h1>
<div class="description">
<p>
WordCount Plugin for CKEditor that counts the words an shows the word count in the footer of the editor.</a>.
</p>
<p>
In order to use the new plugin, include it in the <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-extraPlugins">config.extraPlugins</a></code> configuration setting.
</p>
<pre class="samples">
CKEDITOR.replace( '<em>textarea_id</em>', {
<strong>extraPlugins: 'wordcount'</strong>
} );
</pre>
</div>
<textarea cols="80" id="editor1" name="editor1" rows="10">
This is some <strong>sample text</strong>. You are using <a href="http://ckeditor.com/">CKEditor</a>.
</textarea>
<script>
CKEDITOR.replace('editor1', {
extraPlugins: 'wordcount'
});
</script>
<div id="footer">
<hr>
<p>
CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
</p>
<p id="copy">
Copyright &copy; 2003-2015, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
Knabben. All rights reserved.
</p>
</div>
</body>
</html>

@ -0,0 +1,110 @@
<!DOCTYPE html>
<!--
Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
-->
<html>
<head>
<meta charset="utf-8">
<title>WordCount &mdash; CKEditor Sample</title>
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="../../../ckeditor.js"></script>
<link href="../../../samples/sample.css" rel="stylesheet">
<meta name="ckeditor-sample-name" content="WordCount plugin">
<meta name="ckeditor-sample-group" content="Plugins">
<meta name="ckeditor-sample-description" content="Counts the words an shows the word count in the footer of the editor.">
<meta name="ckeditor-sample-isnew" content="1">
<script>
CKEDITOR.disableAutoInline = true;
</script>
</head>
<body>
<h1 class="samples">
<a href="../../../samples/index.html">CKEditor Samples</a> &raquo; WordCount Plugin
</h1>
<div class="description">
<p>
WordCount Plugin for CKEditor that counts the words an shows the word count in the footer of the editor.</a>.
</p>
<p>
In order to use the new plugin, include it in the <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-extraPlugins">config.extraPlugins</a></code> configuration setting.
</p>
<pre class="samples">
CKEDITOR.replace( '<em>textarea_id</em>', {
<strong>extraPlugins: 'wordcount',
maxWordCount: 4,
maxCharCount: 10,
// optional events
paragraphsCountGreaterThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationparagraphs").css("background-color", "crimson").css("color", "white").text(currentLength + "/" + maxLength + " - paragraphs").show();
},
wordCountGreaterThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationword").css("background-color", "crimson").css("color", "white").text(currentLength + "/" + maxLength + " - word").show();
},
charCountGreaterThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationchar").css("background-color", "crimson").css("color", "white").text(currentLength + "/" + maxLength + " - char").show();
},
charCountLessThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationchar").css("background-color", "white").css("color", "black").hide();
},
paragraphsCountLessThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationparagraphs").css("background-color", "white").css("color", "black").hide();
},
wordCountLessThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationword").css("background-color", "white").css("color", "black").hide();
}</strong>
} );
</pre>
</div>
<textarea cols="80" id="editor1" name="editor1" rows="10">
This is some <strong>sample text</strong>. You are using <a href="http://ckeditor.com/">CKEditor</a>.
</textarea>
<div id="informationchar"></div>
<div id="informationword"></div>
<div id="informationparagraphs"></div>
<script>
CKEDITOR.replace('editor1', {
extraPlugins: 'wordcount',
wordcount: {
showWordCount: true,
showCharCount: true,
maxWordCount: 4,
maxCharCount: 10,
paragraphsCountGreaterThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationparagraphs").css("background-color", "crimson").css("color", "white").text(currentLength + "/" + maxLength + " - paragraphs").show();
},
wordCountGreaterThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationword").css("background-color", "crimson").css("color", "white").text(currentLength + "/" + maxLength + " - word").show();
},
charCountGreaterThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationchar").css("background-color", "crimson").css("color", "white").text(currentLength + "/" + maxLength + " - char").show();
},
charCountLessThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationchar").css("background-color", "white").css("color", "black").hide();
},
paragraphsCountLessThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationparagraphs").css("background-color", "white").css("color", "black").hide();
},
wordCountLessThanMaxLengthEvent: function (currentLength, maxLength) {
$("#informationword").css("background-color", "white").css("color", "black").hide();
}
}
});
</script>
<div id="footer">
<hr>
<p>
CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
</p>
<p id="copy">
Copyright &copy; 2003-2015, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
Knabben. All rights reserved.
</p>
</div>
</body>
</html>
Loading…
Cancel
Save