update
This commit is contained in:
16
.htaccess
Normal file
16
.htaccess
Normal file
@@ -0,0 +1,16 @@
|
||||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_URI} !phpmyadmin
|
||||
RewriteCond %{REQUEST_URI} !szablon
|
||||
RewriteCond %{REQUEST_URI} !crossdomain.xml
|
||||
RewriteCond %{REQUEST_URI} !Admin
|
||||
RewriteCond %{REQUEST_URI} !error.html
|
||||
RewriteCond %{REQUEST_URI} !rekbufor.html
|
||||
RewriteRule !\.(js|ico|gif|jpg|png|ICO|GIF|JPG|PNG|css|svg|swf|flv|pdf|PDF|php|eot|woff|ttf|otf)$ index.php
|
||||
|
||||
ModPagespeed off
|
||||
|
||||
#
|
||||
#AuthType Basic
|
||||
#AuthName "Password Protected Area"
|
||||
#AuthUserFile Static/.htpasswd
|
||||
#Require valid-user
|
||||
2
.vscode/ftp-kr.json
vendored
2
.vscode/ftp-kr.json
vendored
@@ -6,7 +6,7 @@
|
||||
"protocol": "ftp",
|
||||
"port": 0,
|
||||
"fileNameEncoding": "utf8",
|
||||
"autoUpload": false,
|
||||
"autoUpload": true,
|
||||
"autoDelete": false,
|
||||
"autoDownload": false,
|
||||
"ignoreRemoteModification": true,
|
||||
|
||||
8
Admin/.htaccess
Normal file
8
Admin/.htaccess
Normal file
@@ -0,0 +1,8 @@
|
||||
RewriteEngine on
|
||||
|
||||
RewriteCond %{REQUEST_URI} !fckeditor
|
||||
RewriteCond %{REQUEST_URI} !ckeditor
|
||||
|
||||
RewriteRule !\.(js|ico|gif|jpg|png|css|ttf)$ index.php
|
||||
|
||||
ModPagespeed off
|
||||
163
Admin/controller/BoxController.php
Normal file
163
Admin/controller/BoxController.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/**
|
||||
* $Id$
|
||||
* klient
|
||||
*
|
||||
*/
|
||||
class BoxController extends MainController implements ControllerInterface {
|
||||
|
||||
const PATH_BANER = '/upload/home';
|
||||
const COUNT_BOX = 4;
|
||||
|
||||
const AVATAR_DEST_DIR = '/upload/home';
|
||||
const AVATAR_TEMP_DIR = '/upload/temp';
|
||||
const MAX_AVATAR_FILE_SIZE = 5; //Rozmiar w mb
|
||||
const CROPPER_BIG_PHOTO_MAX_WIDTH = 800;
|
||||
const CROPPER_BIG_PHOTO_MAX_HEIGHT = 800;
|
||||
//const PHOTO_WIDTH = 288;
|
||||
//const PHOTO_HEIGHT = 127;
|
||||
|
||||
const IMAGE_MINI_WIDTH = 170;
|
||||
const IMAGE_MINI_HEIGHT = 130;
|
||||
//const IMAGE_NORMAL_WIDTH = 627;
|
||||
//const IMAGE_NORMAL_HEIGHT = 219;
|
||||
/**
|
||||
* 170px × 130px
|
||||
* Domyslna metoda
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$countArray = range(0, 3);
|
||||
//Utils::ArrayDisplay($param);
|
||||
$dalData = MfHomeSiteDAL::GetDalDataObj();
|
||||
//$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->setCondition(array('lang' =>$lang));
|
||||
$dalData->setLimit(4);
|
||||
|
||||
$arrayObjHome = MfHomeSiteDAL::GetResult($dalData);
|
||||
|
||||
//Utils::ArrayDisplay($countArray);
|
||||
$arrayToEdit = array();
|
||||
foreach ($countArray as $key => $element) {
|
||||
if (key_exists($key, $arrayObjHome)) {
|
||||
$arrayToEdit[] = $arrayObjHome[$key];
|
||||
} else {
|
||||
$arrayToEdit[] = MfHomeSiteDAL::GetEmptyObj();
|
||||
}
|
||||
}
|
||||
//Utils::ArrayDisplay($arrayToEdit);
|
||||
$this->smarty->assign('arrayToEdit', $arrayToEdit);
|
||||
$this->smarty->assign('lang', $lang);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Dodawanie/edycja klient/banera
|
||||
*
|
||||
*/
|
||||
public function EditAction($param) {
|
||||
$countArray = range(0, 3);
|
||||
$post = Request::GetAllPost();
|
||||
foreach ($countArray as $key => $element) {
|
||||
$objHomeElement = MfHomeSiteDAL::GetById($post['elementId'][$key]);
|
||||
//$objHomeElement = new MfHomeSite();
|
||||
$objHomeElement->SetName($post['elementName'][$key]);
|
||||
$objHomeElement->SetSourceUrl($post['elementUrl'][$key]);
|
||||
$objHomeElement->SetDescription($post['elementText'][$key]);
|
||||
|
||||
|
||||
if($_FILES['elementImg_'.$key]['tmp_name']) {
|
||||
|
||||
$photoSize = getimagesize($_FILES['elementImg_'.$key]['tmp_name']);
|
||||
$photoProp = $photoSize[0] / $photoSize[1];
|
||||
|
||||
$photoWidth = $photoSize[0];
|
||||
$photoHeight = $photoSize[1];
|
||||
|
||||
if ($photoWidth > self::CROPPER_BIG_PHOTO_MAX_WIDTH) {
|
||||
$photoHeight = self::CROPPER_BIG_PHOTO_MAX_WIDTH / $photoProp;
|
||||
$photoWidth = self::CROPPER_BIG_PHOTO_MAX_WIDTH;
|
||||
}
|
||||
|
||||
if ($photoHeight > self::CROPPER_BIG_PHOTO_MAX_HEIGHT) {
|
||||
$photoWidth = self::CROPPER_BIG_PHOTO_MAX_HEIGHT * $photoProp;
|
||||
$photoHeight = self::CROPPER_BIG_PHOTO_MAX_HEIGHT;
|
||||
}
|
||||
|
||||
$photoFile = PhotoDAL::SimplePhotoUpload($_FILES['elementImg_'.$key], self::AVATAR_TEMP_DIR . DIRECTORY_SEPARATOR , $photoWidth, $photoHeight, 100);
|
||||
|
||||
|
||||
|
||||
$destName = md5('photo' . microtime());
|
||||
if(file_exists(PATH_STATIC_CONTENT.'upload/home/'.$destName.'.jpg'))
|
||||
unlink(PATH_STATIC_CONTENT.'upload/home/'.$destName.'.jpg');
|
||||
|
||||
|
||||
$propW = $photoWidth/self::IMAGE_MINI_WIDTH;
|
||||
$propH = $photoHeight/self::IMAGE_MINI_HEIGHT;
|
||||
|
||||
if ($propW > $propH) {
|
||||
$prop = $propH;
|
||||
} else {
|
||||
$prop = $propW;
|
||||
}
|
||||
$photoMini = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/home', 0, 0, self::IMAGE_MINI_WIDTH*$prop, self::IMAGE_MINI_HEIGHT*$prop, self::IMAGE_MINI_WIDTH, self::IMAGE_MINI_HEIGHT);
|
||||
$objHomeElement->SetPhoto($photoMini);
|
||||
}
|
||||
|
||||
|
||||
|
||||
MfHomeSiteDAL::Save($objHomeElement);
|
||||
//Utils::ArrayDisplay($objHomeElement);
|
||||
}
|
||||
|
||||
$this->AddRedirect(Router::GenerateUrl('editBox', array('_value' => 'Box')), 0);
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
|
||||
//Utils::ArrayDisplay($_FILES);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Metoda wspolna
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
$this->Run($param);
|
||||
//$admin = AuthDAL::GetAdmin();
|
||||
$this->RunShared('Auth', array());
|
||||
$this->smarty->assign('titleAdmin', 'Strona główna');
|
||||
$this->smarty->assign('lang', $param['lang']);
|
||||
// $struct = array(
|
||||
// 'User' => array('User' => 'Index'),
|
||||
// 'Słowniki' => array('Dictionary' => 'Index'),
|
||||
// //'Role' => array('Acl' => 'Index'),
|
||||
// //'Uprawnienia' => array('Acl' => 'Rules'),
|
||||
// 'Zmienne serwisu' => array('Setup' => 'Index')
|
||||
//
|
||||
//
|
||||
// );
|
||||
|
||||
$this->smarty->assign('structure','');
|
||||
|
||||
}
|
||||
|
||||
private function renderStruct($struct){
|
||||
$return = array();
|
||||
|
||||
foreach($struct AS $k => $row){
|
||||
$return[] = '<a href="' . Router::GenerateUrl('dictpig',$row).'">'.$k.'</a>';
|
||||
}
|
||||
|
||||
return implode("<br />",$return);
|
||||
}
|
||||
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
326
Admin/controller/CalcController.php
Normal file
326
Admin/controller/CalcController.php
Normal file
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* $Id$
|
||||
* Słownki
|
||||
*
|
||||
*/
|
||||
class CalcController extends MainController implements ControllerInterface {
|
||||
|
||||
const CONTENT_PER_PAGE = 50;
|
||||
|
||||
/**
|
||||
* Domyślna metoda
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
|
||||
|
||||
if (isset($param['type'])) {
|
||||
SessionProxy::SetValue('typeCalc', $param['type']);
|
||||
} else {
|
||||
$param['type'] = 1;
|
||||
}
|
||||
SessionProxy::SetValue('typeCalc', $param['type']);
|
||||
$dalData = MfParametersDAL::GetDalDataObj();
|
||||
$dalData->addCondition('type', $param['type']);
|
||||
$dalData->setSortBy('sort');
|
||||
|
||||
$arrayObjParameters = MfParametersDAL::GetResult($dalData);
|
||||
//Utils::ArrayDisplay($arrayObjParameters);
|
||||
//===grupowanie====
|
||||
$arrayParam = array();
|
||||
$arrayGroupParam = array();
|
||||
foreach ($arrayObjParameters as $objParam) {
|
||||
$idLink = $objParam->GetLinkId();
|
||||
$arrayGroupParam[$objParam->GetLinkId()][] = $objParam;
|
||||
}
|
||||
|
||||
$this->smarty->assign('arrayObj', $arrayObjParameters);
|
||||
$this->smarty->assign('arrayGroupParam', $arrayGroupParam);
|
||||
}
|
||||
|
||||
public function AddAction($param) {
|
||||
|
||||
$objParameters = new MfParameters();
|
||||
$objParameters->setType(SessionProxy::GetValue('typeCalc'));
|
||||
$this->smarty->assign('obj', $objParameters);
|
||||
|
||||
if (Request::GetPost('doCategoryEdit')) {
|
||||
Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
$priceProgres = Request::Get('price_progres');
|
||||
$priceProgres ? $priceProgres = 1 : $priceProgres = '0';
|
||||
|
||||
$objParameters->setPublication($publication);
|
||||
$objParameters->setPrice($data['price']);
|
||||
$objParameters->setLinkId($data['link_id']);
|
||||
$objParameters->setName($data['name']);
|
||||
$objParameters->setOpis($data['opis']);
|
||||
$objParameters->setPriceProgres($priceProgres);
|
||||
$objParameters->setCountProgres($data['count_progres']);
|
||||
$objParameters->setUnit($data['unit']);
|
||||
|
||||
if (empty($out)) {
|
||||
|
||||
//Utils::ArrayDisplay($objParameters);
|
||||
$idParameters = MfParametersDAL::Save($objParameters);
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editConfig', array('Calc' => 'Index', 'type' => $objParameters->getType())));
|
||||
} else {
|
||||
|
||||
$this->smarty->assign('obj', $objParameters);
|
||||
|
||||
|
||||
$this->smarty->assign('info', 'Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type', 'error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error', $error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function EditAction($param) {
|
||||
|
||||
$objParameters = MfParametersDAL::GetById($param['id']);
|
||||
$this->smarty->assign('obj', $objParameters);
|
||||
|
||||
if (Request::GetPost('doCategoryEdit')) {
|
||||
Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
$priceProgres = Request::Get('price_progres');
|
||||
$priceProgres ? $priceProgres = 1 : $priceProgres = '0';
|
||||
|
||||
$objParameters->setPublication($publication);
|
||||
$objParameters->setPrice($data['price']);
|
||||
$objParameters->setLinkId($data['link_id']);
|
||||
$objParameters->setName($data['name']);
|
||||
$objParameters->setOpis($data['opis']);
|
||||
$objParameters->setCountProgres($data['count_progres']);
|
||||
$objParameters->setPriceProgres($priceProgres);
|
||||
$objParameters->setUnit($data['unit']);
|
||||
|
||||
if (empty($out)) {
|
||||
|
||||
//Utils::ArrayDisplay($objParameters);
|
||||
$idParameters = MfParametersDAL::Save($objParameters);
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editConfig', array('Calc' => 'Index', 'type' => $objParameters->getType())));
|
||||
} else {
|
||||
|
||||
$this->smarty->assign('obj', $objParameters);
|
||||
|
||||
|
||||
$this->smarty->assign('info', 'Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type', 'error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error', $error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function DeleteAction($param) {
|
||||
|
||||
|
||||
$arrayObjDict = MfDictionaryDAL::GetResult(array('id_mf_dictionary' => $param['id']), array(), 1, 'mf_dictionary.keyword ASC');
|
||||
if (count($arrayObjDict) > 0) {
|
||||
MfDictionaryDAL::DeleteByKey($arrayObjDict[0]->GetKeyword());
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->AddRedirect(Router::GenerateUrl('DictLabel', array("Dictionary" => 'Index')), 0);
|
||||
}
|
||||
|
||||
public function GenerateModAction($param) {
|
||||
MFLog::Info(__FUNCTION__);
|
||||
//require_once('../core/lib/Smarty/Smarty.class.php');
|
||||
//$smarty = new Smarty();
|
||||
// $smarty->template_dir = Config::Get('PATH_SMARTY_TEMPLATE');
|
||||
// $smarty->compile_dir = Config::Get('PATH_SMARTY_COMPILE');
|
||||
|
||||
$db = Registry::Get('db');
|
||||
|
||||
$sql = " select table_name from information_schema.tables where table_schema <> 'information_schema' ";
|
||||
$stmt = $db->prepare($sql)
|
||||
->execute($sql);
|
||||
|
||||
$tables = $stmt->FetchAllRow();
|
||||
foreach ($tables as $table) {
|
||||
|
||||
$tableName = $table[0];
|
||||
$className = ucfirst(Utils::SQLName2PHPName($tableName));
|
||||
|
||||
$this->smarty->assign('tableName', $tableName);
|
||||
$this->smarty->assign('className', $className);
|
||||
|
||||
// zależne obiekty/tabele działa dopiero od mySQL 5.1.16
|
||||
// $sql = " select table_name from referential_constraints where constraint_schema <> 'information_schema' and referenced_table_name = '$tableName' ";
|
||||
// $stmt = $db->prepare($sql)
|
||||
// ->execute($sql);
|
||||
//
|
||||
// $refTableNames = array();
|
||||
//
|
||||
// $refTables = $stmt->FetchAllRow();
|
||||
// foreach ($refTables as $refTable) {
|
||||
// $tmp_name = Utils::SQLName2PHPName($refTable[0]);
|
||||
// $refTables[$refTable[0]] = $tmp_name;
|
||||
// }
|
||||
//
|
||||
// $smarty->assign('refTables', $refTables);
|
||||
// kolumny tabeli dla obiektu
|
||||
|
||||
$sql = " select column_name from information_schema.columns where table_name='$tableName'; ";
|
||||
$stmt = $db->prepare($sql)
|
||||
->execute($sql);
|
||||
|
||||
|
||||
$columnNames = array();
|
||||
|
||||
|
||||
$columns = $stmt->FetchAllRow();
|
||||
foreach ($columns as $column) {
|
||||
if ($column[0] === 'id_' . $tableName) {
|
||||
$tmp_name = 'id';
|
||||
} else {
|
||||
$tmp_name = Utils::SQLName2PHPName($column[0]);
|
||||
}
|
||||
$columnNames[$column[0]] = $tmp_name;
|
||||
}
|
||||
|
||||
|
||||
$this->smarty->assign('columnNames', $columnNames);
|
||||
|
||||
$output = '<?php' . $this->smarty->fetch('templateModel.tpl') . '?>';
|
||||
$file = fopen(PATH_MODEL_TMP . $className . '.class.php', "w");
|
||||
fwrite($file, $output);
|
||||
fclose($file);
|
||||
|
||||
$outputDAL = '<?php' . $this->smarty->fetch('templateModelDAL.tpl') . '?>';
|
||||
$file = fopen(PATH_MODEL_TMP . $className . 'DAL.class.php', "w");
|
||||
fwrite($file, $outputDAL);
|
||||
fclose($file);
|
||||
}
|
||||
}
|
||||
|
||||
public function GenOneModelAction($param) {
|
||||
// kolumny tabeli dla obiektu
|
||||
|
||||
$tableName = 'fk_maps';
|
||||
|
||||
$db = Registry::Get('db');
|
||||
$sql = " select column_name from information_schema.columns where table_name='$tableName'; ";
|
||||
$stmt = $db->prepare($sql)
|
||||
->execute($sql);
|
||||
|
||||
$className = ucfirst(Utils::SQLName2PHPName($tableName));
|
||||
|
||||
$this->smarty->assign('tableName', $tableName);
|
||||
$this->smarty->assign('className', $className);
|
||||
|
||||
$columnNames = array();
|
||||
$columns = $stmt->fetchAllAssoc();
|
||||
//Utils::ArrayDisplay($columns);
|
||||
//$columns = $stmt->FetchAllRow();
|
||||
foreach ($columns as $column) {
|
||||
//Utils::ArrayDisplay($column);
|
||||
if ($column['COLUMN_NAME'] === 'id_mf_participant') {
|
||||
$tmp_name = 'id';
|
||||
} else {
|
||||
$tmp_name = Utils::SQLName2PHPName($column['COLUMN_NAME']);
|
||||
}
|
||||
$columnNames[$column['COLUMN_NAME']] = $tmp_name;
|
||||
}
|
||||
//Utils::ArrayDisplay($this->smarty);
|
||||
|
||||
$this->smarty->assign('columnNames', $columnNames);
|
||||
|
||||
$output = '<?php' . $this->smarty->fetch('partial/Calc/templateModel.tpl') . '?>';
|
||||
//Utils::ArrayDisplay($this->smarty);
|
||||
$file = fopen(PATH_MODEL_TMP . $className . '.class.php', "w");
|
||||
fwrite($file, $output);
|
||||
fclose($file);
|
||||
|
||||
$outputDAL = '<?php' . $this->smarty->fetch('partial/Calc/templateModelDAL.tpl') . '?>';
|
||||
$file = fopen(PATH_MODEL_TMP . $className . 'DAL.class.php', "w");
|
||||
fwrite($file, $outputDAL);
|
||||
fclose($file);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Metoda wspolna
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
|
||||
$this->RunShared('Auth', $param);
|
||||
$this->Run($param);
|
||||
$admin = AuthDAL::GetAdmin();
|
||||
$this->user = $admin;
|
||||
|
||||
$this->smarty->assign('titleAdmin', 'Formularz');
|
||||
$struct = array(
|
||||
//'User' => array('User' => 'Index'),
|
||||
'Parametry' => array('Calc' => 'Index', 'type' => 1),
|
||||
//'Parametry mieszkanie' => array('Calc' => 'Index', 'type' => 2),
|
||||
'Treści' => array('HomeSite' => 'EditArticle')
|
||||
);
|
||||
|
||||
$this->smarty->assign('structure', $this->renderStruct($struct));
|
||||
}
|
||||
|
||||
private function renderStruct($struct) {
|
||||
$return = '';
|
||||
|
||||
foreach ($struct AS $k => $row) {
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig', $row) . '">' . $k . '</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
440
Admin/controller/ConfigController.php
Normal file
440
Admin/controller/ConfigController.php
Normal file
@@ -0,0 +1,440 @@
|
||||
<?php
|
||||
/**
|
||||
* Kontroler konfigurator
|
||||
*
|
||||
*/
|
||||
class ConfigController extends MainController implements ControllerInterface {
|
||||
|
||||
|
||||
|
||||
|
||||
const CONTENT_PER_PAGE = 5;
|
||||
|
||||
|
||||
/**
|
||||
* Strona glowna
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
$dalData = MfStepDAL::GetDalDataObj();
|
||||
$arrayObjStep = MfStepDAL::GetResult($dalData);
|
||||
// Utils::ArrayDisplay($arrayObjStep[0]->getStepElement());
|
||||
$this->smarty->assign('arrayObj', $arrayObjStep);
|
||||
}
|
||||
|
||||
public function AddStructureAction($param) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function AddAction($param) {
|
||||
|
||||
$objStep = MfStepDAL::GetEmptyObj();
|
||||
|
||||
if (Request::GetPost('doCategoryAdd')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
$objStep->setPublication($publication);
|
||||
$objStep->setWeight($data['weight']);
|
||||
$objStep->setLang('pl');
|
||||
$objStep->setName($data['name']);
|
||||
$objStep->setDescription($data['description']);
|
||||
$objStep->setDateAdd(Utils::GetNowDate());
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
$idStep = MfStepDAL::Save($objStep);
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editConfig', array('Config' => 'Index')));
|
||||
} else {
|
||||
|
||||
$this->smarty->assign('obj',$objStep);
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
}
|
||||
}
|
||||
$this->smarty->assign('obj',$objStep);
|
||||
}
|
||||
|
||||
|
||||
public function EditAction($param) {
|
||||
|
||||
$objStep = MfStepDAL::GetById($param['id'], $param['lang']);
|
||||
$this->smarty->assign('obj', $objStep);
|
||||
|
||||
if (Request::GetPost('doCategoryEdit')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
$objStep->setPublication($publication);
|
||||
$objStep->setWeight($data['weight']);
|
||||
$objStep->setLang('pl');
|
||||
$objStep->setName($data['name']);
|
||||
$objStep->setDescription($data['description']);
|
||||
$objStep->setDateEdit(Utils::GetNowDate());
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
//Utils::ArrayDisplay($objStep);
|
||||
$idStep = MfStepDAL::Save($objStep);
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editConfig', array('Config' => 'Index')));
|
||||
} else {
|
||||
|
||||
$this->smarty->assign('obj',$objStep);
|
||||
|
||||
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
|
||||
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function DeleteAction($param) {
|
||||
$dalData = MfStepElementDAL::GetDalDataObj();
|
||||
$dalData->setCount(true);
|
||||
$dalData->addCondition('id_mf_step', $param['id']);
|
||||
|
||||
$count = MfStepElementDAL::GetResult($dalData);
|
||||
|
||||
$delete = true;
|
||||
$error = '';
|
||||
if ($count > 0 ) {
|
||||
$delete = false;
|
||||
}
|
||||
|
||||
if ($delete) {
|
||||
$objStep = MfStepDAL::GetById($param['id']);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$dalData = MfStepDAL::GetDalDataObj();
|
||||
$dalData->setObj($objStep);
|
||||
MfStepDAL::Delete($dalData);
|
||||
$this->AddRedirectInfo('Element został usunięty', 'ok', Router::GenerateUrl('editCategory', array('Config' => 'Index')));
|
||||
} else {
|
||||
if ($count) {
|
||||
$error .= 'Grupa posiada elementy';
|
||||
}
|
||||
// if ($isLang) {
|
||||
// $error .= $error ? '<br/><br/>' : '';
|
||||
// $error .= 'Kategoria posiada wersję jezykową';
|
||||
// }
|
||||
$this->AddRedirectInfo($error, 'error', Router::GenerateUrl('editCategory', array('Config' => 'Index')));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function IndexElementAction($param) {
|
||||
$dalData = MfStepDAL::GetDalDataObj();
|
||||
$arrayObjStep = MfStepDAL::GetResult($dalData);
|
||||
// Utils::ArrayDisplay($arrayObjStep[0]->getStepElement());
|
||||
$this->smarty->assign('arrayObj', $arrayObjStep);
|
||||
}
|
||||
|
||||
public function AddElementAction($param) {
|
||||
$idMain = $param['idMain'];
|
||||
$objStepElement = MfStepElementDAL::GetEmptyObj();
|
||||
|
||||
if (Request::GetPost('doCategoryAdd')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
$other = Request::Get('other');
|
||||
$other ? $other = 1 : $other = '0';
|
||||
|
||||
$objStepElement->setOther($other);
|
||||
$objStepElement->setIdMfStep($idMain);
|
||||
$objStepElement->setPublication($publication);
|
||||
$objStepElement->setWeight($data['weight']);
|
||||
$objStepElement->setLang('pl');
|
||||
$objStepElement->setName($data['name']);
|
||||
$objStepElement->setDescription($data['description']);
|
||||
$objStepElement->setDateAdd(Utils::GetNowDate());
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
$idStep = MfStepElementDAL::Save($objStepElement);
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editConfig', array('Config' => 'Edit', 'id' => $idMain)));
|
||||
} else {
|
||||
|
||||
$this->smarty->assign('obj',$objStepElement);
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
}
|
||||
}
|
||||
$this->smarty->assign('obj',$objStepElement);
|
||||
$this->smarty->assign('idMain',$idMain);
|
||||
}
|
||||
|
||||
|
||||
public function EditElementAction($param) {
|
||||
$idMain = $param['idMain'];
|
||||
$objStepElement = MfStepElementDAL::GetById($param['id'], $param['lang']);
|
||||
$this->smarty->assign('obj', $objStepElement);
|
||||
|
||||
$this->smarty->assign('idMain',$idMain);
|
||||
|
||||
|
||||
if (Request::GetPost('doCategoryEdit')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
$other = Request::Get('other');
|
||||
$other ? $other = 1 : $other = '0';
|
||||
|
||||
$objStepElement->setOther($other);
|
||||
$objStepElement->setIdMfStep($idMain);
|
||||
$objStepElement->setPublication($publication);
|
||||
$objStepElement->setWeight($data['weight']);
|
||||
$objStepElement->setLang('pl');
|
||||
$objStepElement->setName($data['name']);
|
||||
$objStepElement->setDescription($data['description']);
|
||||
$objStepElement->setDateEdit(Utils::GetNowDate());
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
//Utils::ArrayDisplay($objStep);
|
||||
$idStep = MfStepElementDAL::Save($objStepElement);
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editConfig', array('Config' => 'Edit', 'id' => $idMain)));
|
||||
} else {
|
||||
|
||||
$this->smarty->assign('obj',$objStep);
|
||||
|
||||
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
|
||||
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function ArchiveAction($param) {
|
||||
|
||||
$dalData = MfConfigArchiveDAL::GetDalDataObj();
|
||||
$page = 1;
|
||||
|
||||
if(isset($param['p']) && $param['p'] > 0) {
|
||||
$page = $param['p'];
|
||||
|
||||
}
|
||||
|
||||
SessionProxy::SetValue('__news_page_no__', $page);
|
||||
|
||||
$offset = ($page - 1) * self::CONTENT_PER_PAGE;
|
||||
$param['ajax'] = 'GetTableContent($(this).attr(\'href\'), \'#tableContentClient\', $(\'#search\').val(), $(\'#linkedList\').val())';
|
||||
//$this->smarty->assign('ajax',$param['ajax']);
|
||||
$dalData->setCount(true);
|
||||
try {
|
||||
$limit = Utils::PageConfigure($this->smarty, $param, ceil(MfConfigArchiveDAL::GetResult($dalData)), self::CONTENT_PER_PAGE);
|
||||
} catch (Exception $e) {
|
||||
Utils::ArrayDisplay($e);
|
||||
}
|
||||
$dalData->setCount(false);
|
||||
$dalData->setSortBy('date_add DESC');
|
||||
$dalData->setLimit($limit);
|
||||
$arrayObj = MfConfigArchiveDAL::GetResult($dalData, false);
|
||||
$this->smarty->assign('arrayObj', $arrayObj);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function AjaxArchiveAction($param) {
|
||||
$this->SetAjaxRender();
|
||||
$dalData = MfConfigArchiveDAL::GetDalDataObj();
|
||||
$page = 1;
|
||||
|
||||
|
||||
$search= trim(Request::GetPost('search'));
|
||||
$status = Request::GetPost('linked');
|
||||
$arraySearch = explode(' ', $search);
|
||||
if (count($arraySearch) > 0) {
|
||||
$where = ' ( ';
|
||||
foreach ($arraySearch as $key => $search) {
|
||||
$where .= $key == 0 ? '' : ' OR ';
|
||||
$where .= ' company LIKE "%'.Utils::AddSlashes($search).'%" ';
|
||||
}
|
||||
$where .= ' ) ';
|
||||
|
||||
$dalData->addCondition(' ', $where, ' ');
|
||||
}
|
||||
$dalData->addCondition('status', $status);
|
||||
|
||||
if(isset($param['p']) && $param['p'] > 0) {
|
||||
$page = $param['p'];
|
||||
}
|
||||
SessionProxy::SetValue('__news_page_no__', $page);
|
||||
|
||||
$offset = ($page - 1) * self::CONTENT_PER_PAGE;
|
||||
$param['ajax'] = 'GetTableContent($(this).attr(\'href\'), \'#tableContentClient\', $(\'#search\').val(), $(\'#linkedList\').val())';
|
||||
//$this->smarty->assign('ajax',$param['ajax']);
|
||||
$dalData->setCount(true);
|
||||
try {
|
||||
$limit = Utils::PageConfigure($this->smarty, $param, ceil(MfConfigArchiveDAL::GetResult($dalData)), self::CONTENT_PER_PAGE);
|
||||
} catch (Exception $e) {
|
||||
Utils::ArrayDisplay($e);
|
||||
}
|
||||
$dalData->setCount(false);
|
||||
$dalData->setSortBy('date_add DESC');
|
||||
$dalData->setLimit($limit);
|
||||
$arrayObj = MfConfigArchiveDAL::GetResult($dalData, false);
|
||||
$this->smarty->assign('arrayObj', $arrayObj);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function ShowArchiveAction($param) {
|
||||
$obj = MfConfigArchiveDAL::GetById($param['id']);
|
||||
$this->smarty->assign('obj', $obj);
|
||||
}
|
||||
|
||||
|
||||
public function AjaxArchiveStatusAction($param) {
|
||||
$this->SetNoRender();
|
||||
$data = Request::GetAllPost();
|
||||
if (Request::GetPost('id') > 0) {
|
||||
$obj = MfConfigArchiveDAL::GetById($data['id']);
|
||||
$obj->setStatus($data['status']);
|
||||
MfConfigArchiveDAL::Save($obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wspolna metoda
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
|
||||
//$this->RunShared('Admin');
|
||||
$this->AddScript('structure.js');
|
||||
$this->Run($param);
|
||||
//$admin = AuthDAL::GetAdmin();
|
||||
$this->RunShared('Auth', array());
|
||||
$this->smarty->assign('titleAdmin', 'CRM');
|
||||
$struct = array(
|
||||
//'User' => array('User' => 'Index'),
|
||||
'Konfigurator' => array('Config' => 'Index'),
|
||||
'-> Historia konfiguracji' => array('Config' => 'Archive'),
|
||||
'Demo' => array('Demo' => 'Index'),
|
||||
'-> Historia pobierania' => array('Demo' => 'File'),
|
||||
'Pliki' => array('File' => 'Index'),
|
||||
'Klienci' => array('Client' => 'Index'),
|
||||
'Strefa Poradnik' => array('Structure' => 'Edit', 'id' => 30),
|
||||
'Strefa Aktualne promocje' => array('Structure' => 'Edit', 'id' => 31),
|
||||
|
||||
|
||||
);
|
||||
|
||||
$this->smarty->assign('structure',$this->renderStruct($struct));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function renderStruct($struct){
|
||||
$return = '';
|
||||
|
||||
foreach($struct AS $k => $row){
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig',$row).'">'.$k.'</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
268
Admin/controller/DemoController.php
Normal file
268
Admin/controller/DemoController.php
Normal file
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
/**
|
||||
|
||||
* Kontroler Demo
|
||||
*
|
||||
*/
|
||||
class DemoController extends MainController implements ControllerInterface {
|
||||
|
||||
|
||||
|
||||
const CONTENT_PER_PAGE = 30;
|
||||
|
||||
|
||||
/**
|
||||
* Strona glowna
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
|
||||
|
||||
$this->AddScript('structure.js');
|
||||
|
||||
$dalData = MfClientDAL::GetDalDataObj();
|
||||
$page = 1;
|
||||
$countStart = 0;
|
||||
|
||||
if(isset($param['strona']) && $param['strona'] > 0) {
|
||||
$page = $param['strona'];
|
||||
$countStart = ($page-1)*self::CONTENT_PER_PAGE;
|
||||
}
|
||||
|
||||
SessionProxy::SetValue('__news_page_no__', $page);
|
||||
|
||||
$offset = ($page - 1) * self::CONTENT_PER_PAGE;
|
||||
$param['ajax'] = 'GetTableContent($(this).attr(\'href\'), \'#tableContentClient\', $(\'#search\').val(), $(\'#linkedList\').val(), $(\'#sortVal\').val())';
|
||||
//$this->smarty->assign('ajax',$param['ajax']);
|
||||
$dalData->setCount(true);
|
||||
|
||||
$dalData->addCondition('type', 5);
|
||||
try {
|
||||
$limit = Utils::PageConfigure($this->smarty, $param, ceil(MfClientDAL::GetResult($dalData)), self::CONTENT_PER_PAGE);
|
||||
} catch (Exception $e) {
|
||||
Utils::ArrayDisplay($e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$sortNameASC = '';
|
||||
$sortNameDESC = '';
|
||||
$sortIdASC = '';
|
||||
$sortIdDESC = '';
|
||||
|
||||
$sortDateAddDESC = '';
|
||||
$sortDateAddASC = '';
|
||||
$sortVal = Request::GetPost('sortVal');
|
||||
switch (Request::GetPost('sortVal')) {
|
||||
case 'last_name DESC':
|
||||
$sortNameDESC = 'Act';
|
||||
break;
|
||||
case 'last_name ASC':
|
||||
$sortNameASC = 'Act';
|
||||
break;
|
||||
case 'id_mf_client DESC':
|
||||
$sortIdDESC = 'Act';
|
||||
break;
|
||||
case 'id_mf_client ASC':
|
||||
$sortIdASC = 'Act';
|
||||
break;
|
||||
default:
|
||||
$sortVal = 'last_name';
|
||||
$sortNameASC = 'Act';
|
||||
}
|
||||
|
||||
|
||||
$dalData->setCount(false);
|
||||
$dalData->setSortBy($sortVal);
|
||||
$dalData->setLimit($limit);
|
||||
$dalData->addCondition('type', 5);
|
||||
$arrayObjClient = MfClientDAL::GetResult($dalData, false);
|
||||
$this->smarty->assign('arrayObj', $arrayObjClient);
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjClient);
|
||||
|
||||
$this->smarty->assign('sortVal', 'last_name');
|
||||
|
||||
$this->smarty->assign('sortNameASC', $sortNameASC);
|
||||
$this->smarty->assign('sortNameDESC', $sortNameDESC);
|
||||
$this->smarty->assign('sortIdASC', $sortIdASC);
|
||||
$this->smarty->assign('sortIdDESC', $sortIdDESC);
|
||||
$this->smarty->assign('sortDateAddASC', $sortDateAddASC);
|
||||
$this->smarty->assign('sortDateAddDESC', $sortDateAddDESC);
|
||||
|
||||
$this->smarty->assign('countStart', $countStart);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function AjaxListAction($param) {
|
||||
$this->AddScript('structure.js');
|
||||
$this->SetAjaxRender();
|
||||
$dalData = MfClientDAL::GetDalDataObj();
|
||||
$page = 1;
|
||||
$countStart = 0;
|
||||
|
||||
if(isset($param['strona']) && $param['strona'] > 0) {
|
||||
$page = $param['strona'];
|
||||
$countStart = ($page-1)*self::CONTENT_PER_PAGE;
|
||||
}
|
||||
|
||||
SessionProxy::SetValue('__news_page_no__', $page);
|
||||
|
||||
$offset = ($page - 1) * self::CONTENT_PER_PAGE;
|
||||
$param['ajax'] = 'GetTableContent($(this).attr(\'href\'), \'#tableContentClient\', $(\'#search\').val(), $(\'#linkedList\').val(), $(\'#sortVal\').val())';
|
||||
$this->smarty->assign('ajax',$param['ajax']);
|
||||
$dalData->setCount(true);
|
||||
|
||||
$dalData->addCondition('type', 5);
|
||||
try {
|
||||
$limit = Utils::PageConfigure($this->smarty, $param, ceil(MfClientDAL::GetResult($dalData, false)), self::CONTENT_PER_PAGE);
|
||||
} catch (Exception $e) {
|
||||
Utils::ArrayDisplay($e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$sortNameASC = '';
|
||||
$sortNameDESC = '';
|
||||
$sortIdASC = '';
|
||||
$sortIdDESC = '';
|
||||
$sortDateAddDESC = '';
|
||||
$sortDateAddASC = '';
|
||||
$sortVal = Request::GetPost('sortVal');
|
||||
switch (Request::GetPost('sortVal')) {
|
||||
case 'last_name DESC':
|
||||
$sortNameDESC = 'Act';
|
||||
break;
|
||||
case 'last_name ASC':
|
||||
$sortNameASC = 'Act';
|
||||
break;
|
||||
case 'id_mf_client DESC':
|
||||
$sortIdDESC = 'Act';
|
||||
break;
|
||||
case 'id_mf_client ASC':
|
||||
$sortIdASC = 'Act';
|
||||
break;
|
||||
case 'date_add ASC':
|
||||
$sortDateAddASC = 'Act';
|
||||
break;
|
||||
case 'date_add DESC':
|
||||
$sortDateAddDESC = 'Act';
|
||||
break;
|
||||
default:
|
||||
$sortVal = 'last_name';
|
||||
$sortNameASC = 'Act';
|
||||
}
|
||||
|
||||
|
||||
$dalData->setCount(false);
|
||||
$dalData->setSortBy($sortVal);
|
||||
$dalData->setLimit($limit);
|
||||
$arrayObjClient = MfClientDAL::GetResult($dalData, false);
|
||||
$this->smarty->assign('arrayObj', $arrayObjClient);
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjClient);
|
||||
|
||||
|
||||
$this->smarty->assign('sortNameASC', $sortNameASC);
|
||||
$this->smarty->assign('sortNameDESC', $sortNameDESC);
|
||||
$this->smarty->assign('sortIdASC', $sortIdASC);
|
||||
$this->smarty->assign('sortIdDESC', $sortIdDESC);
|
||||
$this->smarty->assign('sortDateAddASC', $sortDateAddASC);
|
||||
$this->smarty->assign('sortDateAddDESC', $sortDateAddDESC);
|
||||
$this->smarty->assign('countStart', $countStart);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function ViewAction($param) {
|
||||
$objClient = MfClientDAL::GetById($param['id']);
|
||||
$this->smarty->assign('obj', $objClient);
|
||||
|
||||
//===FILE=======================================
|
||||
$dalData = MfFileDemoLogsDAL::GetDalDataObj();
|
||||
$dalData->addCondition('id_mf_client',$param['id']);
|
||||
//Utils::ArrayDisplay($_SERVER);
|
||||
//$dalData->setJoin(array('objFile' => ' LEFT JOIN mf_file ON mf_article.id_mf_article=mf_article_description.id_mf_article'));
|
||||
$arrayObj = MfFileDemoLogsDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObjFile', $arrayObj);
|
||||
//----------------------------------------------
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function FileAction($param) {
|
||||
|
||||
$dalData = MfFileDemoDAL::GetDalDataObj();
|
||||
$arrayObj = MfFileDemoDAL::GetResult($dalData);
|
||||
|
||||
$dalData = MfFileDemoLogsDAL::GetDalDataObj();
|
||||
//$dalData->setCount(true);
|
||||
foreach ($arrayObj as $obj) {
|
||||
$dalData->addCondition('id_mf_file_demo', $obj->getId());
|
||||
$arrayByFile[$obj->getId()] = MfFileDemoLogsDAL::GetResult($dalData);
|
||||
}
|
||||
//Utils::ArrayDisplay($arrayByFile);
|
||||
$this->smarty->assign('arrayObj', $arrayObj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function AddStructureAction($param) {
|
||||
$this->SetNoRender();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wspolna metoda
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
|
||||
//$this->RunShared('Admin');
|
||||
|
||||
$this->Run($param);
|
||||
//$admin = AuthDAL::GetAdmin();
|
||||
$this->RunShared('Auth', array());
|
||||
$this->smarty->assign('titleAdmin', 'CRM');
|
||||
$struct = array(
|
||||
//'User' => array('User' => 'Index'),
|
||||
'Konfigurator' => array('Config' => 'Index'),
|
||||
'-> Historia konfiguracji' => array('Config' => 'Archive'),
|
||||
'Demo' => array('Demo' => 'Index'),
|
||||
'-> Historia pobierania' => array('Demo' => 'File'),
|
||||
'Pliki' => array('File' => 'Index'),
|
||||
'Klienci' => array('Client' => 'Index'),
|
||||
'Strefa Poradnik' => array('Structure' => 'Edit', 'id' => 30),
|
||||
'Strefa Aktualne promocje' => array('Structure' => 'Edit', 'id' => 31),
|
||||
|
||||
|
||||
);
|
||||
|
||||
$this->smarty->assign('structure',$this->renderStruct($struct));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function renderStruct($struct){
|
||||
$return = '';
|
||||
|
||||
foreach($struct AS $k => $row){
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig',$row).'">'.$k.'</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
180
Admin/controller/DictionaryController.php
Normal file
180
Admin/controller/DictionaryController.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
/**
|
||||
* $Id$
|
||||
* Słownki
|
||||
*
|
||||
*/
|
||||
class DictionaryController extends MainController implements ControllerInterface {
|
||||
|
||||
|
||||
|
||||
const CONTENT_PER_PAGE = 50;
|
||||
|
||||
/**
|
||||
* Domyślna metoda
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
|
||||
//Utils::ArrayDisplay($param);
|
||||
//$dalData->setCount(true);
|
||||
if (isset($param['location'])) {
|
||||
$location = 1;
|
||||
} else {
|
||||
$location = 0;
|
||||
}
|
||||
|
||||
|
||||
$limit = Utils::PageConfigure($this->smarty, $param, ceil( MfDictionaryDAL::GetResult(array('lang' => "'pl'", 'location' => $location), array(), null, null, true)), self::CONTENT_PER_PAGE);
|
||||
|
||||
$arrayObjDict = MfDictionaryDAL::GetResult(array('lang' => "'pl'", 'location' => $location), array(), $limit, 'mf_dictionary.keyword ASC');
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjDict);
|
||||
$this->smarty->assign('arrayObjDict', $arrayObjDict);
|
||||
}
|
||||
|
||||
public function AjaxIndexAction($param) {
|
||||
$this->SetAjaxRender();
|
||||
$where = '';
|
||||
if (isset($param['location'])) {
|
||||
$location = 1;
|
||||
} else {
|
||||
$location = 0;
|
||||
}
|
||||
|
||||
$search= trim(Request::GetPost('search'));
|
||||
$arraySearch = explode(' ', $search);
|
||||
if (count($arraySearch) > 0) {
|
||||
$where = ' ( ';
|
||||
foreach ($arraySearch as $key => $search) {
|
||||
$where .= $key == 0 ? '' : ' OR ';
|
||||
$where .= ' mf_dictionary.keyword LIKE "%'.addslashes($search).'%" ';
|
||||
}
|
||||
$where .= ' ) ';
|
||||
}
|
||||
|
||||
$limit = Utils::PageConfigure($this->smarty, $param, ceil( MfDictionaryDAL::GetResult(array('lang' => "'pl'", 'location' => $location, '' => array('condition' => '', 'value' => $where)), array(), null, null, true)), 600);
|
||||
|
||||
$arrayObjDict = MfDictionaryDAL::GetResult(array('lang' => "'pl'", 'location' => $location, ' ' => array('condition' => '', 'value' => $where)), array(), $limit, 'mf_dictionary.keyword ASC');
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjDict);
|
||||
$this->smarty->assign('arrayObjDict', $arrayObjDict);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function EditAction($param) {
|
||||
|
||||
if (isset($param['id'])) {
|
||||
|
||||
|
||||
$arrayObjDict = MfDictionaryDAL::GetResult(array('id_mf_dictionary' => $param['id']), array(), 1, 'mf_dictionary.keyword ASC');
|
||||
if (!(count($arrayObjDict) > 0)) {
|
||||
$this->AddRedirect(Router::GenerateUrl('DictLabel', array("Dictionary" => 'Index')));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (Request::GetPost('doDictEdit')) {
|
||||
$post = Request::GetAllPost(false);
|
||||
//Utils::ArrayDisplay($post);
|
||||
|
||||
foreach ($post['replacement'] as $langDict => $replacement) {
|
||||
|
||||
|
||||
|
||||
$arrayObjDict = MfDictionaryDAL::GetResult(array('keyword' => "'".$post['keyword']."'", 'lang' => "'".$langDict."'"), array(), 1, 'mf_dictionary.keyword ASC');
|
||||
//Utils::ArrayDisplay($arrayObjDict);
|
||||
if (key_exists(0, $arrayObjDict)) {
|
||||
$objDict = $arrayObjDict[0];
|
||||
$objDict->SetReplacement($replacement);
|
||||
MfDictionaryDAL::Save($objDict);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->AddRedirect(Router::GenerateUrl('DictLabel', array("Dictionary" => 'Index')), 0);
|
||||
|
||||
}
|
||||
|
||||
$arrayObjDict = MfDictionaryDAL::GetResult(array('id_mf_dictionary' => $param['id']), array(), 1, 'mf_dictionary.keyword ASC');
|
||||
if (!(count($arrayObjDict) > 0)) {
|
||||
$this->AddRedirect(Router::GenerateUrl('DictLabel', array("Dictionary" => 'Index')), 0);
|
||||
}
|
||||
|
||||
|
||||
$this->smarty->assign('objDict', $arrayObjDict[0]);
|
||||
} else {
|
||||
$this->AddRedirect(Router::GenerateUrl('DictLabel', array("Dictionary" => 'Index')), 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function DeleteAction($param) {
|
||||
|
||||
|
||||
$arrayObjDict = MfDictionaryDAL::GetResult(array('id_mf_dictionary' => $param['id']), array(), 1, 'mf_dictionary.keyword ASC');
|
||||
if (count($arrayObjDict) > 0) {
|
||||
MfDictionaryDAL::DeleteByKey($arrayObjDict[0]->GetKeyword());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->AddRedirect(Router::GenerateUrl('DictLabel', array("Dictionary" => 'Index')), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Metoda wspolna
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
|
||||
$this->RunShared('Auth', $param);
|
||||
$this->Run($param);
|
||||
$admin = AuthDAL::GetAdmin();
|
||||
$this->user = $admin;
|
||||
|
||||
$this->smarty->assign('titleAdmin', 'Administracja');
|
||||
$panelMenu = ARRAY_PANEL_MENU;
|
||||
$struct = $panelMenu['layout'];
|
||||
|
||||
$this->smarty->assign('structure',$this->renderStruct($struct));
|
||||
|
||||
}
|
||||
|
||||
private function renderStruct($struct){
|
||||
$return = '';
|
||||
|
||||
foreach($struct AS $k => $row){
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig',$row).'">'.$k.'</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function postDispatch($param) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
||||
503
Admin/controller/FileController.php
Normal file
503
Admin/controller/FileController.php
Normal file
@@ -0,0 +1,503 @@
|
||||
<?
|
||||
class FileController extends MainController implements ControllerInterface
|
||||
{
|
||||
const AVATAR_DEST_DIR = '/upload/File';
|
||||
const AVATAR_TEMP_DIR = '/upload/temp';
|
||||
const CROPPER_BIG_PHOTO_MAX_WIDTH = 800;
|
||||
const CROPPER_BIG_PHOTO_MAX_HEIGHT = 800;
|
||||
const PHOTO_WIDTH = 283;
|
||||
const PHOTO_HEIGHT = 400;
|
||||
|
||||
const IMAGE_MINI_WIDTH = 283;
|
||||
const IMAGE_MINI_HEIGHT = 400;
|
||||
const IMAGE_NORMAL_WIDTH = 283;
|
||||
const IMAGE_NORMAL_HEIGHT = 400;
|
||||
|
||||
|
||||
|
||||
public function IndexAction($param){
|
||||
|
||||
|
||||
$dalData = MfFileDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array());
|
||||
$dalData->setLimit(10);
|
||||
$dalData->setSortBy('weight');
|
||||
|
||||
|
||||
$arrayFile = MfFileDAL::GetResult($dalData);
|
||||
//Utils::ArrayDisplay($arrayFile);
|
||||
|
||||
}
|
||||
public function IndexStructureAction($param){
|
||||
$this->smarty->assign('icon', true);
|
||||
//Utils::ArrayDisplay($param);
|
||||
if (isset($param['runSharedVariable'])) {
|
||||
$this->smarty->assign('moduleBoxId', $param['runSharedVariable']);
|
||||
$this->smarty->assign('moduleName', $param['moduleName']);
|
||||
}
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$data = array();
|
||||
if (isset($param['id'])) {
|
||||
$data = array('mf_file.id_structure' => $param['id'], 'lang' => $lang);
|
||||
|
||||
} else {
|
||||
$this->smarty->assign('add', true);
|
||||
$this->smarty->assign('icon', false);
|
||||
}
|
||||
|
||||
$dalData = MfFileDAL::GetDalDataObj();
|
||||
$dalData->setCondition($data);
|
||||
$dalData->setSortBy('weight');
|
||||
|
||||
|
||||
$arrayFile = MfFileDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObj', $arrayFile);
|
||||
//Utils::ArrayDisplay($arrayFile);
|
||||
|
||||
}
|
||||
|
||||
public function EditStructureAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$dalData = MfFileDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $lang, 'id_structure' => $param['id']));
|
||||
$dalData->setSortBy('weight');
|
||||
|
||||
|
||||
$arrayFile = MfFileDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObj', $arrayFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Akcja dodawania
|
||||
*
|
||||
* @param <type> $param
|
||||
*/
|
||||
public function AddAction($param) {
|
||||
|
||||
|
||||
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$idStructure = SessionProxy::GetValue('idStructure');
|
||||
if (!$idStructure) {
|
||||
$this->AddRedirect(Router::GenerateUrl('IndexStructure', array('Structure' => 'Index')), 0);
|
||||
}
|
||||
$this->smarty->assign('idStructure', $idStructure);
|
||||
//$idCategory = SessionProxy::GetValue('idCategory');
|
||||
$idCategory = $idStructure;
|
||||
$arrayFileType = Utils::GetArrayList('mf_file_type', 'id_mf_file_type','name');
|
||||
$this->smarty->assign('arrayFileType', $arrayFileType);
|
||||
|
||||
$objFile = MfFileDAL::GetEmptyObj();
|
||||
|
||||
|
||||
if(Request::IsPost()) {
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('title', 'Pole nazwa musi zostać wypełnione.');
|
||||
//$validator->IsDate('datepublication', 'Pole data publikacji musi zostać wypełnione.');
|
||||
//$validator->IsEmpty('description', 'Pole opis musi zostać wypełnione.');
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
//$data['timepublication'] = $data['timepublication'] ? $data['timepublication'] : '00';
|
||||
|
||||
$objFileDescription = $objFile->GetDescriptionObj();
|
||||
|
||||
$objFile->SetDate(Utils::GetNowDate());
|
||||
//$objFile->SetDatePublication($data['datepublication']." ".$data['timepublication'].":00:00");
|
||||
$objFile->SetDatePublication(Utils::GetNowDate());
|
||||
$objFile->SetWeight($data['weight']);
|
||||
$objFile->SetPublication($publication);
|
||||
$objFile->SetType($data['file_type']);
|
||||
$objFile->SetIdStructure($idCategory);
|
||||
$objFile->SetDateUpdate(Utils::GetNowDate());
|
||||
$objFile->SetAddDate(Utils::GetNowDate());
|
||||
$objFile->SetEditDate(Utils::GetNowDate());
|
||||
|
||||
$objFileDescription->SetLang($lang);
|
||||
$objFileDescription->SetDescription($data['description']);
|
||||
$objFileDescription->SetTitle($data['title']);
|
||||
$objFileDescription->SetPublication($publication);
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
|
||||
if($_FILES['filename']['tmp_name']){
|
||||
|
||||
$destName = Utils::TextToUrl($_FILES['filename']['name']);
|
||||
if(file_exists(PATH_STATIC_CONTENT.'upload/File/'.$destName)) {
|
||||
$destName = '1_'.$destName;
|
||||
}
|
||||
|
||||
move_uploaded_file($_FILES['filename']['tmp_name'], PATH_STATIC_CONTENT.'upload/File/'.$destName);
|
||||
umask(0000);
|
||||
@chmod(PATH_STATIC_CONTENT.'upload/File/'.$destName, 0777);
|
||||
$objFile->SetName($destName);
|
||||
}
|
||||
|
||||
|
||||
if( isset($_FILES['photoname']) && $_FILES['photoname']['tmp_name']){
|
||||
|
||||
$photoSize = getimagesize($_FILES['photoname']['tmp_name']);
|
||||
$photoProp = $photoSize[0] / $photoSize[1];
|
||||
|
||||
$photoWidth = $photoSize[0];
|
||||
$photoHeight = $photoSize[1];
|
||||
|
||||
if ($photoWidth > self::CROPPER_BIG_PHOTO_MAX_WIDTH) {
|
||||
$photoHeight = self::CROPPER_BIG_PHOTO_MAX_WIDTH / $photoProp;
|
||||
$photoWidth = self::CROPPER_BIG_PHOTO_MAX_WIDTH;
|
||||
}
|
||||
|
||||
if ($photoHeight > self::CROPPER_BIG_PHOTO_MAX_HEIGHT) {
|
||||
$photoWidth = self::CROPPER_BIG_PHOTO_MAX_HEIGHT * $photoProp;
|
||||
$photoHeight = self::CROPPER_BIG_PHOTO_MAX_HEIGHT;
|
||||
}
|
||||
|
||||
$photoFile = PhotoDAL::SimplePhotoUpload($_FILES['photoname'], self::AVATAR_TEMP_DIR . DIRECTORY_SEPARATOR , $photoWidth, $photoHeight, 100);
|
||||
|
||||
|
||||
|
||||
$destName = md5('photo' . microtime());
|
||||
if(file_exists(PATH_STATIC_CONTENT.'upload/File/'.$destName.'.jpg'))
|
||||
unlink(PATH_STATIC_CONTENT.'upload/File/'.$destName.'.jpg');
|
||||
|
||||
|
||||
$propW = $photoWidth/self::IMAGE_NORMAL_WIDTH;
|
||||
$propH = $photoHeight/self::IMAGE_NORMAL_HEIGHT;
|
||||
|
||||
if ($propW > $propH) {
|
||||
$prop = $propH;
|
||||
} else {
|
||||
$prop = $propW;
|
||||
}
|
||||
|
||||
|
||||
// maks szerokość
|
||||
//$photo = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/File', 0, 0, $photoWidth, $photoHeight, self::IMAGE_NORMAL_WIDTH, $photoWidth/$prop);
|
||||
// maks wysokość
|
||||
//$photo = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/File', 0, 0, $photoWidth, $photoHeight, $photoHeight/$prop, self::IMAGE_NORMAL_HEIGHT);
|
||||
$photo = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/File', 0, 0, self::IMAGE_NORMAL_WIDTH*$prop, self::IMAGE_NORMAL_HEIGHT*$prop, self::IMAGE_NORMAL_WIDTH, self::IMAGE_NORMAL_HEIGHT);
|
||||
|
||||
|
||||
// Utils::ArrayDisplay('$prop: '.$prop);
|
||||
// Utils::ArrayDisplay('$propW: '.$propW);
|
||||
// Utils::ArrayDisplay('$propH: '.$propH);
|
||||
// Utils::ArrayDisplay('$photoHeight: '.$photoHeight);
|
||||
// Utils::ArrayDisplay('$photoWidth: '.$photoWidth);
|
||||
/// Utils::ArrayDisplay('$photoHeight/$prop: '.$photoWidth/$prop);
|
||||
// Utils::ArrayDisplay('self::IMAGE_NORMAL_HEIGHT: '.self::IMAGE_NORMAL_HEIGHT);
|
||||
|
||||
|
||||
//Utils::ArrayDisplay('foto: '.$photo);
|
||||
$objPhoto = new Picture();
|
||||
$objPhoto->SetLink($photo);
|
||||
$objPhoto->SetWeight(1);
|
||||
$objPhoto->SetPublication(1);
|
||||
$idPhoto = PictureDAL::Insert($objPhoto);
|
||||
$objFile->SetIdPicture($idPhoto);
|
||||
$destName = md5('photo' . microtime());
|
||||
|
||||
$propW = $photoWidth/self::IMAGE_MINI_WIDTH;
|
||||
$propH = $photoHeight/self::IMAGE_MINI_HEIGHT;
|
||||
|
||||
if ($propW > $propH) {
|
||||
$prop = $propH;
|
||||
} else {
|
||||
$prop = $propW;
|
||||
}
|
||||
$photoMini = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/File', 0, 0, self::IMAGE_MINI_WIDTH*$prop, self::IMAGE_MINI_HEIGHT*$prop, self::IMAGE_MINI_WIDTH, self::IMAGE_MINI_HEIGHT);
|
||||
//Utils::ArrayDisplay('fotoMini: '.$photoMini);
|
||||
$objPhoto = new Picture();
|
||||
$objPhoto->SetLink($photoMini);
|
||||
$objPhoto->SetWeight(1);
|
||||
$objPhoto->SetPublication(1);
|
||||
$idPhoto = PictureDAL::Insert($objPhoto);
|
||||
$objFile->SetIdPictureMini($idPhoto);
|
||||
}
|
||||
if (isset($data['deletePhoto'])) {
|
||||
$objFile->SetIdPictureMini(0);
|
||||
$objFile->SetIdPicture(0);
|
||||
}
|
||||
|
||||
$iid = MfFileDAL::Save($objFile);
|
||||
$objFileDescription->SetIdMfFile($iid);
|
||||
|
||||
MfFileDescriptionDAL::Save($objFileDescription);
|
||||
|
||||
$this->smarty->assign('iid', $iid);
|
||||
//$this->AddRedirect(Router::GenerateUrl('indexFile', array('File'=> 'Index')), 0);
|
||||
$this->AddRedirect(Router::GenerateUrl('editStructure', array('id' => $idStructure)), 0);
|
||||
|
||||
} else {
|
||||
//$this->content=$this->FormatAjaxOutput($out, $param);
|
||||
//Utils::ArrayDisplay($out);
|
||||
|
||||
$objFile->SetFileDescriptionObj($objFileDescription);
|
||||
$this->smarty->assign('objFile',$objFile);
|
||||
$datePublished = explode(" ",$objFile->GetDatePublication());
|
||||
|
||||
$this->smarty->assign("datePublished", $datePublished[0]);
|
||||
$this->smarty->assign("timePublished", $datePublished[1]);
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Akcja dodawania
|
||||
*
|
||||
* @param <type> $param
|
||||
*/
|
||||
public function EditAction($param) {
|
||||
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$idStructure = SessionProxy::GetValue('idStructure');
|
||||
$this->smarty->assign('idStructure', $idStructure);
|
||||
//$idCategory = SessionProxy::GetValue('idCategory');
|
||||
$idCategory = $idStructure;
|
||||
//$arrayFileType = Utils::GetArrayList('mf_file_type', 'name', $lang);
|
||||
//$this->smarty->assign('arrayFileType', $arrayFileType);
|
||||
|
||||
//$objFile = MfFileDAL::GetEmptyObj();
|
||||
$objFile = MfFileDAL::GetById($param['idFile'], $lang);
|
||||
|
||||
|
||||
if(Request::IsPost()) {
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('title', 'Pole nazwa musi zostać wypełnione.');
|
||||
//$validator->IsDate('datepublication', 'Pole data publikacji musi zostać wypełnione.');
|
||||
//$validator->IsEmpty('description', 'Pole opis musi zostać wypełnione.');
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
$objFileDescription = $objFile->GetDescriptionObj();
|
||||
|
||||
$objFile->SetDate(Utils::GetNowDate());
|
||||
//$objFile->SetDatePublication($data['datepublication']." ".$data['timepublication'].":00:00");
|
||||
$objFile->SetDatePublication(Utils::GetNowDate());
|
||||
$objFile->SetWeight($data['weight']);
|
||||
$objFile->SetPublication($publication);
|
||||
$objFile->SetIdStructure($idCategory);
|
||||
$objFile->SetType($data['file_type']);
|
||||
$objFile->SetDateUpdate(Utils::GetNowDate());
|
||||
$objFile->SetAddDate(Utils::GetNowDate());
|
||||
$objFile->SetEditDate(Utils::GetNowDate());
|
||||
//Utils::ArrayDisplay($objFile);
|
||||
$objFileDescription->SetLang($lang);
|
||||
$objFileDescription->SetDescription($data['description']);
|
||||
$objFileDescription->SetTitle($data['title']);
|
||||
$objFileDescription->SetPublication($publication);
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
|
||||
if($_FILES['filename']['tmp_name']){
|
||||
|
||||
if (file_exists($objFile->GetNamePath())) {
|
||||
unlink($objFile->GetNamePath());
|
||||
}
|
||||
|
||||
$destName = Utils::TextToUrl($_FILES['filename']['name']);
|
||||
if(file_exists(PATH_STATIC_CONTENT.'upload/File/'.$destName)) {
|
||||
$destName = '1_'.$destName;
|
||||
}
|
||||
|
||||
move_uploaded_file($_FILES['filename']['tmp_name'], PATH_STATIC_CONTENT.'upload/File/'.$destName);
|
||||
umask(0000);
|
||||
@chmod(PATH_STATIC_CONTENT.'upload/File/'.$destName, 0777);
|
||||
$objFile->SetName($destName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=obrazki na listę============================================================================================================================================================
|
||||
|
||||
if($_FILES['photoname']['tmp_name']) {
|
||||
|
||||
$photoSize = getimagesize($_FILES['photoname']['tmp_name']);
|
||||
$photoProp = $photoSize[0] / $photoSize[1];
|
||||
|
||||
$photoWidth = $photoSize[0];
|
||||
$photoHeight = $photoSize[1];
|
||||
|
||||
if ($photoWidth > self::CROPPER_BIG_PHOTO_MAX_WIDTH) {
|
||||
$photoHeight = self::CROPPER_BIG_PHOTO_MAX_WIDTH / $photoProp;
|
||||
$photoWidth = self::CROPPER_BIG_PHOTO_MAX_WIDTH;
|
||||
}
|
||||
|
||||
if ($photoHeight > self::CROPPER_BIG_PHOTO_MAX_HEIGHT) {
|
||||
$photoWidth = self::CROPPER_BIG_PHOTO_MAX_HEIGHT * $photoProp;
|
||||
$photoHeight = self::CROPPER_BIG_PHOTO_MAX_HEIGHT;
|
||||
}
|
||||
|
||||
$photoFile = PhotoDAL::SimplePhotoUpload($_FILES['photoname'], self::AVATAR_TEMP_DIR . DIRECTORY_SEPARATOR , $photoWidth, $photoHeight, 100);
|
||||
|
||||
|
||||
|
||||
$destName = md5('photo' . microtime());
|
||||
if(file_exists(PATH_STATIC_CONTENT.'upload/File/'.$destName.'.jpg'))
|
||||
unlink(PATH_STATIC_CONTENT.'upload/File/'.$destName.'.jpg');
|
||||
|
||||
|
||||
$propW = $photoWidth/self::IMAGE_NORMAL_WIDTH;
|
||||
$propH = $photoHeight/self::IMAGE_NORMAL_HEIGHT;
|
||||
|
||||
if ($propW > $propH) {
|
||||
$prop = $propH;
|
||||
} else {
|
||||
$prop = $propW;
|
||||
}
|
||||
|
||||
//$photo = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/Structure', 0, 0, self::IMAGE_NORMAL_WIDTH*$prop, self::IMAGE_NORMAL_HEIGHT*$prop, self::IMAGE_NORMAL_WIDTH, self::IMAGE_NORMAL_HEIGHT);
|
||||
//maks szerokość
|
||||
//$photo = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/File', 0, 0, $photoWidth, $photoHeight, self::IMAGE_NORMAL_WIDTH, $photoWidth/$prop);
|
||||
// maks wysokość
|
||||
//$photo = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/File', 0, 0, $photoWidth, $photoHeight, $photoHeight/$prop, self::IMAGE_NORMAL_HEIGHT);
|
||||
$photo = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/File', 0, 0, self::IMAGE_NORMAL_WIDTH*$prop, self::IMAGE_NORMAL_HEIGHT*$prop, self::IMAGE_NORMAL_WIDTH, self::IMAGE_NORMAL_HEIGHT);
|
||||
|
||||
|
||||
$objPhoto = new Picture();
|
||||
$objPhoto->SetLink($photo);
|
||||
$objPhoto->SetWeight(1);
|
||||
$objPhoto->SetPublication(1);
|
||||
$idPhoto = PictureDAL::Insert($objPhoto);
|
||||
$objFile->SetIdPicture($idPhoto);
|
||||
$destName = md5('photo' . microtime());
|
||||
|
||||
|
||||
$propW = $photoWidth/self::IMAGE_MINI_WIDTH;
|
||||
$propH = $photoHeight/self::IMAGE_MINI_HEIGHT;
|
||||
|
||||
if ($propW > $propH) {
|
||||
$prop = $propH;
|
||||
} else {
|
||||
$prop = $propW;
|
||||
}
|
||||
$photoMini = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/File', 0, 0, self::IMAGE_MINI_WIDTH*$prop, self::IMAGE_MINI_HEIGHT*$prop, self::IMAGE_MINI_WIDTH, self::IMAGE_MINI_HEIGHT);
|
||||
$objPhoto = new Picture();
|
||||
$objPhoto->SetLink($photoMini);
|
||||
$objPhoto->SetWeight(1);
|
||||
$objPhoto->SetPublication(1);
|
||||
$idPhoto = PictureDAL::Insert($objPhoto);
|
||||
$objFile->SetIdPictureMini($idPhoto);
|
||||
}
|
||||
|
||||
if (isset($data['deletePhoto'])) {
|
||||
$objFile->SetIdPictureMini(0);
|
||||
$objFile->SetIdPicture(0);
|
||||
}
|
||||
//===============================================================================================================================================================
|
||||
|
||||
//Utils::ArrayDisplay($objFileDescription);
|
||||
$iid = MfFileDAL::Save($objFile);
|
||||
$objFileDescription->SetIdMfFile($iid);
|
||||
|
||||
MfFileDescriptionDAL::Save($objFileDescription);
|
||||
|
||||
$this->smarty->assign('iid', $iid);
|
||||
//$this->AddRedirect(Router::GenerateUrl('indexFile', array('File'=> 'Index')), 0);
|
||||
$this->AddRedirect(Router::GenerateUrl('editStructure', array('id' => $idStructure)), 0);
|
||||
|
||||
} else {
|
||||
//$this->content=$this->FormatAjaxOutput($out, $param);
|
||||
//Utils::ArrayDisplay($out);
|
||||
|
||||
$objFile->SetFileDescriptionObj($objFileDescription);
|
||||
$this->smarty->assign('objFile',$objFile);
|
||||
$datePublished = explode(" ",$objFile->GetDatePublication());
|
||||
|
||||
$this->smarty->assign("datePublished", $datePublished[0]);
|
||||
$this->smarty->assign("timePublished", $datePublished[1]);
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->smarty->assign('objFile', $objFile);
|
||||
}
|
||||
|
||||
public function DeleteAction($param) {
|
||||
$idStructure = SessionProxy::GetValue('idStructure');
|
||||
//$logger = LoggerManager::getLogger(__CLASS__);
|
||||
|
||||
$idFile = $param['idFile'];
|
||||
if ($idFile) {
|
||||
try {
|
||||
$objFile = MfFileDAL::GetById($idFile);
|
||||
|
||||
if (file_exists($objFile->GetNamePath())) {
|
||||
unlink($objFile->GetNamePath());
|
||||
}
|
||||
|
||||
MfFileDAL::Delete($objFile);
|
||||
|
||||
} catch (Exception $e) {
|
||||
//Utils::ArrayDisplay($e);
|
||||
//$logger->error('bład usunięcia pliku o id: '.$idFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->AddRedirect(Router::GenerateUrl('editStructure', array('id' => $idStructure)), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* preDispatch
|
||||
* @param array $param
|
||||
* @return null
|
||||
*/
|
||||
public function preDispatch($param){
|
||||
$this->Run($param);
|
||||
$this->AddScript('dropDown.js');
|
||||
$this->AddScript('structure.js');
|
||||
$this->AddScript('Dosia.js');
|
||||
$this->AddScript('Link.js');
|
||||
$this->AddScript('drag-drop-folder-tree.js');
|
||||
// //$this->AddScript('Validator.js');
|
||||
$this->AddScript('calendar.js');
|
||||
|
||||
$this->RunShared('Auth', array());
|
||||
|
||||
$this->RunShared('Structure', $param);
|
||||
$this->smarty->assign('idStucture', SessionProxy::GetValue('idStructure'));
|
||||
|
||||
$this->smarty->assign('lang', 'pl');
|
||||
$this->smarty->assign('titleAdmin', 'Pliki');
|
||||
$this->smarty->assign('activeTab', 'index');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* postDispatch
|
||||
* @param array $param
|
||||
* @return null
|
||||
*/
|
||||
public function postDispatch($param){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
257
Admin/controller/HomeController.php
Normal file
257
Admin/controller/HomeController.php
Normal file
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/**
|
||||
* $Id$
|
||||
* klient
|
||||
*
|
||||
*/
|
||||
class HomeController extends MainController implements ControllerInterface {
|
||||
|
||||
const PATH_BANER = '/upload/Banner';
|
||||
/**
|
||||
* Domyslna metoda
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
|
||||
if (!is_dir(PATH_STATIC_CONTENT.self::PATH_BANER)) {
|
||||
mkdir(PATH_STATIC_CONTENT.self::PATH_BANER, 0777);
|
||||
}
|
||||
if (!is_dir(PATH_STATIC_CONTENT.self::PATH_BANER."/".$lang)) {
|
||||
mkdir(PATH_STATIC_CONTENT.self::PATH_BANER."/".$lang, 0777);
|
||||
}
|
||||
|
||||
//AKCJE DOMYSLNE
|
||||
$logger = LoggerManager::getLogger(__CLASS__);
|
||||
|
||||
if(isset($_POST['saveBanners'])) {
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
foreach ($_POST['id'] as $id) {
|
||||
|
||||
$name = $_POST['name'][$id];
|
||||
|
||||
if (isset($_FILES['baner'.$id]) && $_FILES['baner'.$id]['error'] != 4) {
|
||||
//echo "sss ".isset($_FILES['photo']['name']);
|
||||
$fileName = $_FILES['baner'.$id]['name'];
|
||||
$ext = explode(".",$fileName);
|
||||
$fileName = Utils::ClearString($fileName);
|
||||
|
||||
if (is_file(PATH_STATIC_CONTENT.self::PATH_BANER.$id."/".$_POST['banerSaved'.$id])) {
|
||||
unlink(PATH_STATIC_CONTENT.self::PATH_BANER.$id."/".$_POST['banerSaved'.$id]);
|
||||
}
|
||||
|
||||
}
|
||||
else if (isset($_POST['banerSaved'.$id])) {
|
||||
$fileName = $_POST['banerSaved'.$id];
|
||||
}
|
||||
|
||||
if ($_POST['id']) {
|
||||
|
||||
}
|
||||
|
||||
//$idCustomer = $_POST['idCustomer'];
|
||||
|
||||
$id = HomeDAL::Update($id, $name, $fileName, $lang);
|
||||
|
||||
if (!is_dir(PATH_STATIC_CONTENT.self::PATH_BANER."/".$lang."/".$id)) {
|
||||
mkdir(PATH_STATIC_CONTENT.self::PATH_BANER."/".$lang."/".$id, 0777);
|
||||
}
|
||||
CustomerDAL::SaveCustomerFile($_FILES, 'baner'.$id, $fileName, PATH_STATIC_CONTENT.self::PATH_BANER."/".$lang."/".$id);
|
||||
}
|
||||
|
||||
// die(Header('Location: customer'.APPLICATION_FILE_TYPE));
|
||||
}
|
||||
|
||||
$arrayBanner = HomeDAL::GetAll($lang);
|
||||
$this->smarty->assign('arrayBanner', $arrayBanner);
|
||||
//Utils::ArrayDisplay($arrayBanner);
|
||||
$this -> AddScript('AC_RunActiveContent.js');
|
||||
$this->AddScript('swfobject.js');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Dodawanie/edycja klient/banera
|
||||
*
|
||||
*/
|
||||
public function EditAction($param) {
|
||||
|
||||
$logger = LoggerManager::getLogger(__CLASS__);
|
||||
//$this->AddScript('CopyFiles.js');
|
||||
$this->AddScript('prototype.js');
|
||||
$this->AddScript('validateFormCustomer.js');
|
||||
$this->AddScript('CheckUnique.js');
|
||||
|
||||
|
||||
if(isset($param['id'])) {
|
||||
$id=$param['id'];
|
||||
} else{
|
||||
$id = null;
|
||||
}
|
||||
|
||||
if(isset($_POST['saveCustomer'])) {
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
|
||||
$id = $_POST['id'];
|
||||
$name = $_POST['name'];
|
||||
$url = $_POST['url'];
|
||||
$sort = $_POST['sort'];
|
||||
$content = $_POST['content'];
|
||||
if(!strstr($url, "http://")) {
|
||||
$url = "http://".$url;
|
||||
}
|
||||
if (isset($_FILES['baner']) && $_FILES['baner']['error'] != 4) {
|
||||
//echo "sss ".isset($_FILES['photo']['name']);
|
||||
$fileName = $_FILES['baner']['name'];
|
||||
$ext = explode(".",$fileName);
|
||||
$fileName = Utils::ClearString($fileName);
|
||||
|
||||
if (is_file(PATH_CUSTOMER.$id."/".$_POST['banerSaved'])) {
|
||||
unlink(PATH_CUSTOMER.$id."/".$_POST['banerSaved']);
|
||||
}
|
||||
|
||||
}
|
||||
else if (isset($_POST['banerSaved'])) {
|
||||
$fileName = $_POST['banerSaved'];
|
||||
}
|
||||
|
||||
if ($_POST['id']) {
|
||||
|
||||
}
|
||||
|
||||
//$idCustomer = $_POST['idCustomer'];
|
||||
$objCustomer = new Customer($id, $name, $fileName, $content, $url, $sort, $published);
|
||||
$id = CustomerDAL::Save($objCustomer);
|
||||
|
||||
if (!is_dir(PATH_CUSTOMER.$id)) {
|
||||
mkdir(PATH_CUSTOMER.$id, 0777);
|
||||
}
|
||||
CustomerDAL::SaveCustomerFile($_FILES, 'baner', $fileName, PATH_CUSTOMER.$id);
|
||||
die(Header('Location: customer'.APPLICATION_FILE_TYPE));
|
||||
}
|
||||
//AKCJE DOMY<4D>LNE
|
||||
$objCustomer = CustomerDAL::GetCustomerById($id);
|
||||
//Utils::ArrayDisplay($objQuery);
|
||||
$this->smarty->assign('objCustomer', $objCustomer);
|
||||
$this->smarty->assign('id', $id);
|
||||
//Utils::ArrayDisplay($objCustomer);
|
||||
$this->smarty->register_modifier("sslash", "stripslashes");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sprawdzanie unikalno<6E>ci nazwy klient
|
||||
*
|
||||
* @param array $param
|
||||
*/
|
||||
public function AjaxCheckUniqueAction($param) {
|
||||
|
||||
header('Content-Type: text/html; charset=iso-8859-2');
|
||||
|
||||
if ($_POST['value']) {
|
||||
$value = $_POST['value'];
|
||||
} else {
|
||||
$value = "";
|
||||
}
|
||||
if ($_POST['column']) {
|
||||
$column = $_POST['column'];
|
||||
} else {
|
||||
$column = "";
|
||||
}
|
||||
|
||||
$unigue = Utils::CheckUnique('customer', $column, $value);
|
||||
if (!$unigue) {
|
||||
$this->smarty->assign("uniqueInfo", "1");
|
||||
}
|
||||
$this->smarty->assign("column", $column);
|
||||
$template = 'clean.tpl';
|
||||
Registry::Remove('smartyTemplate');
|
||||
Registry::Set('smartyTemplate', $template);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* usuwanie banera
|
||||
*
|
||||
*/
|
||||
public function DeleteAction($param) {
|
||||
|
||||
$logger = LoggerManager::getLogger(__CLASS__);
|
||||
|
||||
$idCustomer = SessionProxy::GetValue(EnumSessionValue::IDCUSTOMER);
|
||||
|
||||
if(isset($param['id'])) {
|
||||
$id=$param['id'];
|
||||
} else{
|
||||
$id = null;
|
||||
}
|
||||
|
||||
if($id) {
|
||||
CustomerDAL::Delete($id);
|
||||
// $filePath = PATH_BILLBOARD.$idCustomer."/".$id.".swf";
|
||||
// if (is_file($filePath)) {
|
||||
// @unlink($filePath);
|
||||
// }
|
||||
die(Header('Location: customer'.APPLICATION_FILE_TYPE));
|
||||
if (Pat) {
|
||||
|
||||
}
|
||||
}
|
||||
//AKCJE DOMY<4D>LNE
|
||||
//Utils::ArrayDisplay($objQuery);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function RedirectAction($param) {
|
||||
if(isset($param) && is_array($param) && !empty($param) && isset($param['id']) && !empty($param['id'])) {
|
||||
$customer = CustomerDAL::GetCustomerById($param['id']);
|
||||
Utils::Redirect($customer -> GetRedirectUrl());
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Metoda wspolna
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
$this->AddScript("prototype.js");
|
||||
$this->AddScript("scriptaculous.js");
|
||||
$this->AddScript("GetContent.js");
|
||||
$this->AddScript("tree.js");
|
||||
$this->AddScript('dropDown.js');
|
||||
$this->AddScript('structure.js');
|
||||
$this->AddScript('Dosia.js');
|
||||
$this->AddScript('Link.js');
|
||||
$this->AddScript('drag-drop-folder-tree.js');
|
||||
$this->AddScript('Validator.js');
|
||||
$this->AddScript('calendar.js');
|
||||
|
||||
//Utils::ArrayDisplay($param);
|
||||
|
||||
$this->Run($param);
|
||||
$this->RunShared('Structure', $param);
|
||||
$this->smarty->assign('titleAdmin', 'Struktura strony');
|
||||
$arrayModuleName = MfModuleDAL::GetArrayModuleName();
|
||||
$this->smarty->assign( 'arrayModuleName' ,$arrayModuleName);
|
||||
$this->smarty->assign('showIcon', true);
|
||||
$this->RunShared('Auth', $param);
|
||||
|
||||
//Utils::ArrayDisplay(Utils::ArrayDisplay(SessionProxy::GetValue(EnumSessionValue::USER_OBJECT)));
|
||||
// if($this->IsUser()==false) {
|
||||
// $this->AddRedirect(URL_MAIN.'/Login.frmx', 0);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
593
Admin/controller/HomeSiteController.php
Normal file
593
Admin/controller/HomeSiteController.php
Normal file
@@ -0,0 +1,593 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* $Id$
|
||||
* klient
|
||||
*
|
||||
*/
|
||||
class HomeSiteController extends MainController implements ControllerInterface {
|
||||
|
||||
const PATH_BANER = '/upload/home';
|
||||
const COUNT_BOX = 6;
|
||||
const AVATAR_DEST_DIR = '/upload/home';
|
||||
const LOGO_DEST_DIR = '/upload/logo';
|
||||
const AVATAR_TEMP_DIR = '/upload/temp';
|
||||
const MAX_AVATAR_FILE_SIZE = 5; //Rozmiar w mb
|
||||
const CROPPER_BIG_PHOTO_MAX_WIDTH = 800;
|
||||
const CROPPER_BIG_PHOTO_MAX_HEIGHT = 800;
|
||||
const CROPPER_BIG_PHOTO_MAX_WIDTH_BANER = 1000;
|
||||
const CROPPER_BIG_PHOTO_MAX_HEIGHT_BANER = 1000;
|
||||
//const PHOTO_WIDTH = 288;
|
||||
//const PHOTO_HEIGHT = 127;
|
||||
|
||||
const IMAGE_MINI_WIDTH = 450;
|
||||
const IMAGE_MINI_HEIGHT = 200;
|
||||
const IMAGE_MINI_WIDTH_BANER = 1024;
|
||||
const IMAGE_MINI_HEIGHT_BANER = 385;
|
||||
|
||||
//const IMAGE_NORMAL_WIDTH = 627;
|
||||
//const IMAGE_NORMAL_HEIGHT = 219;
|
||||
/**
|
||||
* 170px × 130px
|
||||
* Domyslna metoda
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
//$this->SetAjaxRender();
|
||||
$dalData = StructureDAL::GetDalDataObj();
|
||||
$dalData->addCondition('publication', 1);
|
||||
$dalData->setSortBy('name');
|
||||
$arrayObjElement = StructureDAL::GetResult($dalData);
|
||||
//Utils::ArrayDisplay($arrayObjElement);
|
||||
//Utils::ArrayDisplay($param);
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$countArray = range(0, 3);
|
||||
//Utils::ArrayDisplay($param);
|
||||
$dalData = MfHomeSiteDAL::GetDalDataObj();
|
||||
//$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->setCondition(array('lang' =>$lang));
|
||||
$dalData->setLimit(4);
|
||||
|
||||
$arrayObjHome = MfHomeSiteDAL::GetResult($dalData);
|
||||
|
||||
//Utils::ArrayDisplay($countArray);
|
||||
$arrayToEdit = array();
|
||||
foreach ($countArray as $key => $element) {
|
||||
if (key_exists($key, $arrayObjHome)) {
|
||||
$arrayToEdit[] = $arrayObjHome[$key];
|
||||
} else {
|
||||
$arrayToEdit[] = MfHomeSiteDAL::GetEmptyObj();
|
||||
}
|
||||
}
|
||||
//Utils::ArrayDisplay($arrayToEdit);
|
||||
$this->smarty->assign('arrayObjElement', $arrayObjElement);
|
||||
$this->smarty->assign('arrayToEdit', $arrayToEdit);
|
||||
$this->smarty->assign('lang', $lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dodawanie/edycja klient/banera
|
||||
*
|
||||
*/
|
||||
public function EditAction($param) {
|
||||
$countArray = range(0, 3);
|
||||
$post = Request::GetAllPost();
|
||||
foreach ($countArray as $key => $element) {
|
||||
$objHomeElement = MfHomeSiteDAL::GetById($post['elementId'][$key]);
|
||||
//$objHomeElement = new MfHomeSite();
|
||||
$objHomeElement->SetName($post['elementName'][$key]);
|
||||
$objHomeElement->SetSourceUrl($post['elementUrl'][$key]);
|
||||
$objHomeElement->SetDescription($post['elementText'][$key]);
|
||||
$objHomeElement->SetTitle($post['elementTitle'][$key]);
|
||||
|
||||
//$objHomeElement->SetIdSource($post['idElement'][$key]);
|
||||
|
||||
|
||||
// if ($_FILES['elementImg_' . $key]['tmp_name']) {
|
||||
//
|
||||
//// $photoSize = getimagesize($_FILES['elementImg_'.$key]['tmp_name']);
|
||||
//// $photoProp = $photoSize[0] / $photoSize[1];
|
||||
//// $photoWidth = $photoSize[0];
|
||||
//// $photoHeight = $photoSize[1];
|
||||
//// if ($photoWidth > self::CROPPER_BIG_PHOTO_MAX_WIDTH) {
|
||||
//// $photoHeight = self::CROPPER_BIG_PHOTO_MAX_WIDTH / $photoProp;
|
||||
//// $photoWidth = self::CROPPER_BIG_PHOTO_MAX_WIDTH;
|
||||
//// }
|
||||
//// if ($photoHeight > self::CROPPER_BIG_PHOTO_MAX_HEIGHT) {
|
||||
//// $photoWidth = self::CROPPER_BIG_PHOTO_MAX_HEIGHT * $photoProp;
|
||||
//// $photoHeight = self::CROPPER_BIG_PHOTO_MAX_HEIGHT;
|
||||
//// }
|
||||
//// $photoFile = PhotoDAL::SimplePhotoUpload($_FILES['elementImg_'.$key], self::AVATAR_TEMP_DIR . DIRECTORY_SEPARATOR , $photoWidth, $photoHeight, 100);
|
||||
//
|
||||
//
|
||||
//
|
||||
// $destName = md5('photo' . microtime());
|
||||
// if (file_exists(PATH_STATIC_CONTENT . 'upload/home/' . $destName . '.jpg'))
|
||||
// unlink(PATH_STATIC_CONTENT . 'upload/home/' . $destName . '.jpg');
|
||||
//
|
||||
// move_uploaded_file($_FILES['elementImg_' . $key]['tmp_name'], PATH_STATIC_CONTENT . 'upload/home/' . $destName . '.jpg');
|
||||
//
|
||||
//// $propW = $photoWidth/self::IMAGE_MINI_WIDTH;
|
||||
//// $propH = $photoHeight/self::IMAGE_MINI_HEIGHT;
|
||||
//// if ($propW > $propH) {
|
||||
//// $prop = $propH;
|
||||
//// } else {
|
||||
//// $prop = $propW;
|
||||
//// }
|
||||
//// $photoMini = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/home', 0, 0, self::IMAGE_MINI_WIDTH*$prop, self::IMAGE_MINI_HEIGHT*$prop, self::IMAGE_MINI_WIDTH, self::IMAGE_MINI_HEIGHT);
|
||||
// $objHomeElement->SetPhoto($destName . '.jpg');
|
||||
// }
|
||||
|
||||
|
||||
|
||||
MfHomeSiteDAL::Save($objHomeElement);
|
||||
//Utils::ArrayDisplay($objHomeElement);
|
||||
}
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editHomeSite', array('_value' => 'HomeSite')), 0);
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
//Utils::ArrayDisplay($_FILES);
|
||||
}
|
||||
|
||||
public function LinksAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$countArray = range(0, 5);
|
||||
//Utils::ArrayDisplay($param);
|
||||
$dalData = MfHomeSiteLinkDAL::GetDalDataObj();
|
||||
//$dalData->setCondition(array('lang' => $param['lang']));
|
||||
//$dalData->setCondition(array('lang' =>$lang));
|
||||
$dalData->setLimit(6);
|
||||
|
||||
$arrayObjHome = MfHomeSiteLinkDAL::GetResult($dalData);
|
||||
|
||||
//Utils::ArrayDisplay($countArray);
|
||||
$arrayToEdit = array();
|
||||
foreach ($countArray as $key => $element) {
|
||||
if (key_exists($key, $arrayObjHome)) {
|
||||
$arrayToEdit[] = $arrayObjHome[$key];
|
||||
} else {
|
||||
$arrayToEdit[] = MfHomeSiteLinkDAL::GetEmptyObj();
|
||||
}
|
||||
}
|
||||
//Utils::ArrayDisplay($arrayToEdit);
|
||||
$this->smarty->assign('arrayToEdit', $arrayToEdit);
|
||||
$this->smarty->assign('lang', $lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dodawanie/edycja klient/banera
|
||||
*
|
||||
*/
|
||||
public function EditLinkAction($param) {
|
||||
$countArray = range(0, 5);
|
||||
$post = Request::GetAllPost();
|
||||
foreach ($countArray as $key => $element) {
|
||||
$objHomeElement = MfHomeSiteLinkDAL::GetById($post['elementId'][$key]);
|
||||
//$objHomeElement = new MfHomeSite();
|
||||
$objHomeElement->SetName($post['elementName'][$key]);
|
||||
$objHomeElement->SetSourceUrl($post['elementUrl'][$key]);
|
||||
//$objHomeElement->SetDescription($post['elementText'][$key]);
|
||||
MfHomeSiteLinkDAL::Save($objHomeElement);
|
||||
//Utils::ArrayDisplay($objHomeElement);
|
||||
}
|
||||
$this->AddRedirect(Router::GenerateUrl('editHomeSite', array('HomeSite' => 'links')), 0);
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
//Utils::ArrayDisplay($_FILES);
|
||||
}
|
||||
|
||||
public function BanerAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$countArray = range(0, 9);
|
||||
//Utils::ArrayDisplay($param);
|
||||
$dalData = MfHomeSiteBanerDAL::GetDalDataObj();
|
||||
//$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->setCondition(array('lang' =>$lang));
|
||||
$dalData->setLimit(10);
|
||||
$dalData->setSortBy('sort');
|
||||
|
||||
$arrayObjHome = MfHomeSiteBanerDAL::GetResult($dalData);
|
||||
|
||||
//Utils::ArrayDisplay($countArray);
|
||||
$arrayToEdit = array();
|
||||
foreach ($countArray as $key => $element) {
|
||||
if (key_exists($key, $arrayObjHome)) {
|
||||
$arrayToEdit[] = $arrayObjHome[$key];
|
||||
} else {
|
||||
$arrayToEdit[] = MfHomeSiteBanerDAL::GetEmptyObj();
|
||||
}
|
||||
}
|
||||
//Utils::ArrayDisplay($arrayToEdit);
|
||||
$this->smarty->assign('arrayToEdit', $arrayToEdit);
|
||||
$this->smarty->assign('lang', $lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dodawanie/edycja klient/banera
|
||||
*
|
||||
*/
|
||||
public function EditBanerAction($param) {
|
||||
|
||||
$countArray = range(0, 9);
|
||||
$post = Request::GetAllPost();
|
||||
//Utils::ArrayDisplay($post);
|
||||
//Utils::ArrayDisplay($_FILES);
|
||||
foreach ($countArray as $key => $element) {
|
||||
$objHomeElement = MfHomeSiteBanerDAL::GetById($post['elementId'][$key]);
|
||||
//$objHomeElement = new MfHomeSite();
|
||||
$objHomeElement->SetName($post['elementName'][$key]);
|
||||
$objHomeElement->SetSourceUrl($post['elementUrl'][$key]);
|
||||
$objHomeElement->SetSort($post['elementSort'][$key]);
|
||||
$objHomeElement->SetDescription($post['elementText'][$key]);
|
||||
|
||||
|
||||
if ($_FILES['elementImg_' . $key]['tmp_name']) {
|
||||
|
||||
$photoSize = getimagesize($_FILES['elementImg_' . $key]['tmp_name']);
|
||||
$photoProp = $photoSize[0] / $photoSize[1];
|
||||
|
||||
$photoWidth = $photoSize[0];
|
||||
$photoHeight = $photoSize[1];
|
||||
|
||||
if ($photoWidth > self::CROPPER_BIG_PHOTO_MAX_WIDTH_BANER) {
|
||||
$photoHeight = self::CROPPER_BIG_PHOTO_MAX_WIDTH_BANER / $photoProp;
|
||||
$photoWidth = self::CROPPER_BIG_PHOTO_MAX_WIDTH_BANER;
|
||||
}
|
||||
|
||||
if ($photoHeight > self::CROPPER_BIG_PHOTO_MAX_HEIGHT_BANER) {
|
||||
$photoWidth = self::CROPPER_BIG_PHOTO_MAX_HEIGHT_BANER * $photoProp;
|
||||
$photoHeight = self::CROPPER_BIG_PHOTO_MAX_HEIGHT_BANER;
|
||||
}
|
||||
|
||||
//$photoFile = PhotoDAL::SimplePhotoUpload($_FILES['elementImg_'.$key], self::AVATAR_TEMP_DIR . DIRECTORY_SEPARATOR , $photoWidth, $photoHeight, 100);
|
||||
|
||||
|
||||
|
||||
$destName = md5('photo' . microtime());
|
||||
//Utils::ArrayDisplay($_FILES['elementImg_'.$key]['tmp_name']);
|
||||
//Utils::ArrayDisplay(PATH_STATIC_CONTENT.'upload/home/'.$destName.'.jpg');
|
||||
|
||||
include_once (Config::Get('PATH_CORE') . '/lib/WideImage/WideImage.php');
|
||||
|
||||
|
||||
if (file_exists(PATH_STATIC_CONTENT . 'upload/home/' . $destName . '.jpg'))
|
||||
unlink(PATH_STATIC_CONTENT . 'upload/home/' . $destName . '.jpg');
|
||||
|
||||
$img = WideImage::loadFromUpload('elementImg_' . $key);
|
||||
$img->resizeDown('1920', null)->saveToFile(PATH_STATIC_CONTENT . 'upload/home/' . $destName . '.jpg', 90);
|
||||
|
||||
//move_uploaded_file($_FILES['elementImg_' . $key]['tmp_name'], PATH_STATIC_CONTENT . 'upload/home/' . $destName . '.jpg');
|
||||
|
||||
|
||||
$propW = $photoWidth / self::IMAGE_MINI_WIDTH_BANER;
|
||||
$propH = $photoHeight / self::IMAGE_MINI_HEIGHT_BANER;
|
||||
|
||||
if ($propW > $propH) {
|
||||
$prop = $propH;
|
||||
} else {
|
||||
$prop = $propW;
|
||||
}
|
||||
//$photoMini = PhotoDAL::SaveTempFile($photoFile, $destName, '/upload/home', 0, 0, self::IMAGE_MINI_WIDTH_BANER*$prop, self::IMAGE_MINI_HEIGHT_BANER*$prop, self::IMAGE_MINI_WIDTH_BANER, self::IMAGE_MINI_HEIGHT_BANER);
|
||||
$objHomeElement->SetPhoto($destName . '.jpg');
|
||||
}
|
||||
|
||||
if (isset($post['elementClear'][$key])) {
|
||||
$objHomeElement->SetName('');
|
||||
$objHomeElement->SetSourceUrl('');
|
||||
$objHomeElement->SetPhoto('');
|
||||
$objHomeElement->SetSort(100);
|
||||
}
|
||||
MfHomeSiteBanerDAL::Save($objHomeElement);
|
||||
//Utils::ArrayDisplay($objHomeElement);
|
||||
}
|
||||
|
||||
$this->AddRedirect(Router::GenerateUrl('editHomeSite', array('HomeSite' => 'Baner')), 0);
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
//Utils::ArrayDisplay($_FILES);
|
||||
$this->partialTemplate = 'Baner.tpl';
|
||||
}
|
||||
|
||||
public function LogoAction($param) {
|
||||
if (!isset($param['type'])) {
|
||||
$param['type'] = 1;
|
||||
}
|
||||
|
||||
$this->smarty->assign('type', $param['type']);
|
||||
|
||||
$dalData = MfLogaDAL::GetDalDataObj();
|
||||
$dalData->addCondition('type', $param['type']);
|
||||
$arrayObj = MfLogaDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObj', $arrayObj);
|
||||
}
|
||||
|
||||
public function AddLogoAction($param) {
|
||||
if (!isset($param['type'])) {
|
||||
$param['type'] = 1;
|
||||
}
|
||||
|
||||
$obj = MfLogaDAL::GetEmptyObj();
|
||||
|
||||
if (Request::GetPost('doLogoEdit')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
if (!$_FILES['logo']['tmp_name']) {
|
||||
$validator->AddError('logo', 'Dodaj plik');
|
||||
}
|
||||
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$active = Request::Get('active');
|
||||
$active ? $active = 1 : $active = '0';
|
||||
$obj->setPublication($active);
|
||||
$obj->setName($data['name']);
|
||||
$obj->setUrl($data['url']);
|
||||
$obj->setSort($data['sort']);
|
||||
$obj->setType($param['type']);
|
||||
$obj->setDateAdd(Utils::GetNowDate());
|
||||
|
||||
|
||||
|
||||
|
||||
//Utils::ArrayDisplay($out);
|
||||
if (empty($out)) {
|
||||
|
||||
$destNameOrg = $_FILES["logo"]["name"];
|
||||
include(Config::Get('PATH_CORE') . '/lib/WideImage/WideImage.php');
|
||||
move_uploaded_file($_FILES["logo"]["tmp_name"], PATH_STATIC_CONTENT . self::LOGO_DEST_DIR . '/' . $param['type'] . '/' . $destNameOrg);
|
||||
// $img = WideImage::loadFromUpload('logo');
|
||||
// $img->saveToFile(PATH_STATIC_CONTENT.self::LOGO_DEST_DIR.'/'.$destNameOrg);
|
||||
// $img->resizeDown('100%', 75)->saveToFile(PATH_STATIC_CONTENT.self::LOGO_DEST_DIR.'/'.$destNameOrg, 90);
|
||||
$obj->setPhoto($destNameOrg);
|
||||
$idLoga = MfLogaDAL::Save($obj);
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editLoga', array('HomeSite' => 'Logo', 'type' => $param['type'])));
|
||||
} else {
|
||||
|
||||
$this->smarty->assign('obj', $obj);
|
||||
$this->smarty->assign('info', 'Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type', 'error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error', $error);
|
||||
}
|
||||
}
|
||||
$this->smarty->assign('obj', $obj);
|
||||
$this->smarty->assign('type', $param['type']);
|
||||
}
|
||||
|
||||
public function EditLogoAction($param) {
|
||||
if (!isset($param['type'])) {
|
||||
$param['type'] = 1;
|
||||
}
|
||||
|
||||
$dalData = MfLogaDAL::GetDalDataObj();
|
||||
$obj = MfLogaDAL::GetById($param['id']);
|
||||
|
||||
if (Request::GetPost('doLogoEdit')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$active = Request::Get('active');
|
||||
$active ? $active = 1 : $active = '0';
|
||||
$obj->setPublication($active);
|
||||
$obj->setName($data['name']);
|
||||
$obj->setUrl($data['url']);
|
||||
$obj->setSort($data['sort']);
|
||||
$obj->setType($param['type']);
|
||||
$obj->setDateAdd(Utils::GetNowDate());
|
||||
|
||||
|
||||
|
||||
|
||||
//Utils::ArrayDisplay($out);
|
||||
if (empty($out)) {
|
||||
if ($_FILES['logo']['tmp_name']) {
|
||||
$destNameOrg = $_FILES["logo"]["name"];
|
||||
move_uploaded_file($_FILES["logo"]["tmp_name"], PATH_STATIC_CONTENT . self::LOGO_DEST_DIR . '/' . $param['type'] . '/' . $destNameOrg);
|
||||
|
||||
// include(Config::Get('PATH_CORE').'/lib/WideImage/WideImage.php');
|
||||
// $img = WideImage::loadFromUpload('logo');
|
||||
// $img->resizeDown('100%', 75)->saveToFile(PATH_STATIC_CONTENT.self::LOGO_DEST_DIR.'/'.$destNameOrg, 90);
|
||||
$obj->setPhoto($destNameOrg);
|
||||
}
|
||||
$idLoga = MfLogaDAL::Save($obj);
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editLoga', array('HomeSite' => 'Logo', 'type' => $param['type'])));
|
||||
} else {
|
||||
|
||||
$this->smarty->assign('obj', $obj);
|
||||
$this->smarty->assign('info', 'Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type', 'error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error', $error);
|
||||
}
|
||||
}
|
||||
$this->smarty->assign('obj', $obj);
|
||||
}
|
||||
|
||||
public function DeleteLogoAction($param) {
|
||||
$this->SetNoRender();
|
||||
if (!isset($param['type'])) {
|
||||
$param['type'] = 1;
|
||||
}
|
||||
|
||||
$dalData = MfLogaDAL::GetDalDataObj();
|
||||
$obj = MfLogaDAL::GetById($param['id']);
|
||||
if ($obj->getId() > 0) {
|
||||
$dalData->setObj($obj);
|
||||
$param['type'] = $obj->getType();
|
||||
//Utils::ArrayDisplay(PATH_STATIC_CONTENT . self::LOGO_DEST_DIR . '/' . $param['type'] . '/' . $obj->getPhoto());
|
||||
if (file_exists(PATH_STATIC_CONTENT . self::LOGO_DEST_DIR . '/' . $param['type'] . '/' . $obj->getPhoto())) {
|
||||
unlink(PATH_STATIC_CONTENT . self::LOGO_DEST_DIR . '/' . $param['type'] . '/' . $obj->getPhoto());
|
||||
}
|
||||
MfLogaDAL::Delete($dalData);
|
||||
} else {
|
||||
$this->AddRedirectInfo('Brak elementu', 'error', Router::GenerateUrl('editLoga', array('HomeSite' => 'Logo', 'type' => $param['type'])));
|
||||
}
|
||||
$this->AddRedirectInfo('Usunięto', 'ok', Router::GenerateUrl('editLoga', array('HomeSite' => 'Logo', 'type' => $param['type'])));
|
||||
}
|
||||
|
||||
public function BoxAction($param) {
|
||||
|
||||
//Utils::ArrayDisplay($param);
|
||||
//Utils::ArrayDisplay($_FILES);
|
||||
if (Request::GetPost('doBoxEdit')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
if ($_FILES['box']['tmp_name']) {
|
||||
|
||||
|
||||
move_uploaded_file($_FILES['box']['tmp_name'], PATH_STATIC_CONTENT . "/upload/baner.jpg");
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editBox', array('HomeSite' => 'Box')));
|
||||
} else {
|
||||
//Utils::ArrayDisplay('err');
|
||||
$this->AddRedirectInfo('Dodaj plik', 'info', Router::GenerateUrl('editBox', array('HomeSite' => 'Box')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function ArticleBoxAction($param) {
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$dalData = MfArticleBoxDAL::GetDalDataObj();
|
||||
$dalData->setSortBy('weight');
|
||||
$dalData->addCondition('lang', $lang);
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObj = MfArticleBoxDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObj', $arrayObj);
|
||||
|
||||
}
|
||||
|
||||
public function AjaxPublishArticleBoxAction($param) {
|
||||
$this->SetNoRender();
|
||||
$data = Request::GetAllPost();
|
||||
$id = $data['idItem'];
|
||||
$obj = MfArticleBoxDAL::GetById($id);
|
||||
//Utils::ArrayDisplay($obj);
|
||||
if ($obj->GetPublication() > 0) {
|
||||
$obj->setPublication(0);
|
||||
} else {
|
||||
$obj->setPublication(1);
|
||||
}
|
||||
//Utils::ArrayDisplay($obj);
|
||||
$dalData = MfArticleBoxDAL::GetDalDataObj();
|
||||
$dalData->setObj($obj);
|
||||
MfArticleBoxDAL::Save($obj);
|
||||
print $obj->getPublication();
|
||||
}
|
||||
|
||||
public function DeleteArticleBoxAction($param) {
|
||||
if (isset($param['id'])) {
|
||||
$id = $param['id'];
|
||||
$obj = MfArticleBoxDAL::GetById($id);
|
||||
$dalData = MfArticleBoxDAL::GetDalDataObj();
|
||||
$dalData->setObj($obj);
|
||||
MfArticleBoxDAL::Delete($dalData);
|
||||
$this->AddRedirectInfo('Element został usunięty', 'ok', Router::GenerateUrl('', array('HomeSite'=>'ArticleBox')));
|
||||
} else {
|
||||
$this->AddRedirectInfo('Wystąpił błąd', 'error', Router::GenerateUrl('', array('HomeSite'=>'ArticleBox')));
|
||||
}
|
||||
}
|
||||
|
||||
public function EditArticleAction($param) {
|
||||
$arrayIdLang = array('pl' => 1, 'en' => 2);
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
|
||||
if (isset($param['id'])) {
|
||||
$id = $param['id'];
|
||||
$obj = MfArticleBoxDAL::GetById($id);
|
||||
//Utils::ArrayDisplay($obj);
|
||||
if ($obj->getId() != $id) {
|
||||
$dalData = MfArticleBoxDAL::GetDalDataObj();
|
||||
$obj->setId($id);
|
||||
$obj->setLang($lang);
|
||||
$dalData->setObj($obj);
|
||||
MfArticleBoxDAL::Insert($dalData);
|
||||
}
|
||||
$this->smarty->assign('obj', $obj);
|
||||
|
||||
if (Request::IsPost()) {
|
||||
$data = Request::GetAllPost();
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
$obj->setDescription($data['description']);
|
||||
$obj->setShortnote($data['shortnote']);
|
||||
$obj->setPublication($publication);
|
||||
$obj->setLang($lang);
|
||||
$obj->setDatePublication(Utils::GetNowDate());
|
||||
$obj->setName($data['name']);
|
||||
$obj->setWeight($data['weight'] ? $data['weight'] : 0);
|
||||
//$obj->setUrl($data['url']);
|
||||
|
||||
$dalData = MfArticleBoxDAL::GetDalDataObj();
|
||||
$dalData->setObj($obj);
|
||||
MfArticleBoxDAL::Save($obj);
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('', array('HomeSite'=>'ArticleBox')));
|
||||
}
|
||||
} else {
|
||||
$obj = MfArticleBoxDAL::GetEmptyObj();
|
||||
}
|
||||
$this->smarty->assign('obj', $obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Metoda wspolna
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
$this->AddScript('structure.js');
|
||||
$this->Run($param);
|
||||
//$admin = AuthDAL::GetAdmin();
|
||||
$this->RunShared('Auth', array());
|
||||
|
||||
|
||||
$this->smarty->assign('titleAdmin', 'Elementy Strony');
|
||||
$panelMenu = ARRAY_PANEL_MENU;
|
||||
$struct = $panelMenu['layout'];
|
||||
|
||||
$this->smarty->assign('structure', $this->renderStruct($struct));
|
||||
}
|
||||
|
||||
private function renderStruct($struct) {
|
||||
$return = '';
|
||||
|
||||
foreach ($struct AS $k => $row) {
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig', $row) . '">' . $k . '</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
388
Admin/controller/ImageController.php
Normal file
388
Admin/controller/ImageController.php
Normal file
@@ -0,0 +1,388 @@
|
||||
<?php
|
||||
|
||||
class ImageController extends MainController implements ControllerInterface {
|
||||
|
||||
const IMAGE_NORMAL_WIDTH = 1000;
|
||||
const IMAGE_NORMAL_HEIGHT = 800;
|
||||
|
||||
public function IndexAction($param) {
|
||||
$zip = new ZipArchive();
|
||||
$archiveName = PATH_STATIC_CONTENT . 'test.zip';
|
||||
if ($zip->open($archiveName) === true) {
|
||||
//Utils::ArrayDisplay('ss');
|
||||
for ($i = 0; $i < $zip->numFiles; $i++) {
|
||||
$entry = $zip->getNameIndex($i);
|
||||
//Utils::ArrayDisplay('zip://' . $archiveName . '#' . $entry);
|
||||
//Utils::ArrayDisplay(PATH_STATIC_CONTENT . 'temp/zip/' . $entry);
|
||||
copy('zip://' . $archiveName . '#' . $entry, PATH_STATIC_CONTENT . 'temp/zip/' . $entry);
|
||||
}
|
||||
$zip->close();
|
||||
}
|
||||
}
|
||||
|
||||
public function UploadAction($param) {
|
||||
if (!SessionProxy::IsSetValue('_ARRAY_PHOTO_')) {
|
||||
SessionProxy::SetValue('_ARRAY_PHOTO_', array());
|
||||
}
|
||||
$arrayPhoto = SessionProxy::GetValue('_ARRAY_PHOTO_');
|
||||
$this->SetAjaxRender();
|
||||
|
||||
include(Config::Get('PATH_CORE') . '/lib/WideImage/WideImage.php');
|
||||
|
||||
$destDir = 'temp/';
|
||||
|
||||
//Utils::ArrayDisplay($_FILES);
|
||||
if ($_FILES['uploadfile']['name']) {
|
||||
$ext = Utils::FileExtFromName($_FILES['uploadfile']['name']);
|
||||
$uploadFileName = Utils::FileNameFromName($_FILES['uploadfile']['name']);
|
||||
$destNameOrg = 'org_' . $uploadFileName . '_' . md5('photo' . time()) . '.jpg';
|
||||
$destName = $uploadFileName . '_' . md5('photo' . time()) . '.jpg';
|
||||
$destNameth = "th_" . $uploadFileName . '_' . md5('photo' . time()) . '.jpg';
|
||||
if (strtolower($ext) == 'zip') {
|
||||
//======Muliti=ZIP=File====================================================
|
||||
|
||||
move_uploaded_file($_FILES['uploadfile']['tmp_name'], PATH_STATIC_CONTENT . 'temp/zip/' . $_FILES['uploadfile']['name']);
|
||||
$zip = new ZipArchive();
|
||||
$archiveName = PATH_STATIC_CONTENT . 'temp/zip/' . $_FILES['uploadfile']['name'];
|
||||
if ($zip->open($archiveName) === true) {
|
||||
//Utils::ArrayDisplay('ss');
|
||||
for ($i = 0; $i < $zip->numFiles; $i++) {
|
||||
$entry = $zip->getNameIndex($i);
|
||||
// Kopiowanie do temp/zip;
|
||||
$uploadFileName = Utils::FileNameFromName($entry);
|
||||
$destNameOrg = 'org_' . $uploadFileName . '_' . md5('photo' . time()) . '.jpg';
|
||||
$destName = $uploadFileName . '_' . md5('photo' . time()) . '.jpg';
|
||||
$destNameth = "th_" . $uploadFileName . '_' . md5('photo' . time()) . '.jpg';
|
||||
//Utils::ArrayDisplay($entry);
|
||||
copy('zip://' . $archiveName . '#' . $entry, PATH_STATIC_CONTENT . 'temp/zip/' . $entry);
|
||||
|
||||
// wczytywanie do obróbki
|
||||
$img = WideImage::loadFromFile(PATH_STATIC_CONTENT . 'temp/zip/' . $entry);
|
||||
|
||||
$img->saveToFile(PATH_STATIC_CONTENT . $destDir . $destNameOrg, 90);
|
||||
$photoSize = getimagesize(PATH_STATIC_CONTENT . $destDir . $destNameOrg);
|
||||
|
||||
if ($photoSize[0] < $photoSize[1]) {
|
||||
$cropH = true;
|
||||
} else {
|
||||
$cropH = false;
|
||||
}
|
||||
$img = WideImage::loadFromFile(PATH_STATIC_CONTENT . $destDir . $destNameOrg);
|
||||
$img->resizeDown('1000', '800')->saveToFile(PATH_STATIC_CONTENT . $destDir . $destName, 90);
|
||||
//
|
||||
if ($cropH) {
|
||||
// zmieniam zmniejszam obrazem do szerokości a potem go obcinam już tylko po wysokości
|
||||
$img->resizeDown('137', null)->crop('center', 'center', 137, 77)->saveToFile(PATH_STATIC_CONTENT . $destDir . $destNameth, 90);
|
||||
} else {
|
||||
//Poziom OK!
|
||||
// zmieniam zmniejszam obrazem do wysokości a potem go obcinam już tylko po szerokości
|
||||
$img->resizeDown(null, '137')->crop('center', 'center', 137, 77)->saveToFile(PATH_STATIC_CONTENT . $destDir . $destNameth, 90);
|
||||
}
|
||||
|
||||
|
||||
$file = URL_STATIC_CONTENT . $destDir . $destNameth;
|
||||
$array = array($destName => array('normal' => $destName, 'th' => $destNameth, 'full' => $destNameOrg));
|
||||
$arrayPhoto = array_merge($arrayPhoto, $array);
|
||||
SessionProxy::SetValue('_ARRAY_PHOTO_', $arrayPhoto);
|
||||
$this->smarty->assign('photo', PATH_STATIC_CONTENT . $destDir . $destName);
|
||||
unlink(PATH_STATIC_CONTENT . 'temp/zip/' . $entry);
|
||||
}
|
||||
$zip->close();
|
||||
}
|
||||
unlink(PATH_STATIC_CONTENT . 'temp/zip/' . $_FILES['uploadfile']['name']);
|
||||
} else {
|
||||
//======Simple=File====================================================
|
||||
|
||||
$img = WideImage::loadFromUpload('uploadfile');
|
||||
$img->resizeDown('1920', null)->saveToFile(PATH_STATIC_CONTENT . $destDir . $destNameOrg, 90);
|
||||
// $img->saveToFile(PATH_STATIC_CONTENT . $destDir . $destNameOrg, 90);
|
||||
|
||||
$photoSize = getimagesize(PATH_STATIC_CONTENT . $destDir . $destNameOrg);
|
||||
|
||||
//Utils::ArrayDisplay($photoSize);
|
||||
|
||||
if ($photoSize[0] < $photoSize[1]) {
|
||||
$cropH = true;
|
||||
} else {
|
||||
$cropH = false;
|
||||
}
|
||||
$img = WideImage::loadFromFile(PATH_STATIC_CONTENT . $destDir . $destNameOrg);
|
||||
$img->resizeDown('800', '600')->saveToFile(PATH_STATIC_CONTENT . $destDir . $destName, 90);
|
||||
//
|
||||
if ($cropH) {
|
||||
// zmieniam zmniejszam obrazem do szerokości a potem go obcinam już tylko po wysokości
|
||||
$img->resizeDown('137', null)->crop('center', 'center', 137, 77)->saveToFile(PATH_STATIC_CONTENT . $destDir . $destNameth, 90);
|
||||
} else {
|
||||
//Poziom OK!
|
||||
// zmieniam zmniejszam obrazem do wysokości a potem go obcinam już tylko po szerokości
|
||||
$img->resizeDown(null, '137')->crop('center', 'center', 137, 77)->saveToFile(PATH_STATIC_CONTENT . $destDir . $destNameth, 90);
|
||||
}
|
||||
|
||||
|
||||
$file = URL_STATIC_CONTENT . $destDir . $destNameth;
|
||||
$array = array($destName => array('normal' => $destName, 'th' => $destNameth, 'full' => $destNameOrg));
|
||||
$arrayPhoto = array_merge($arrayPhoto, $array);
|
||||
SessionProxy::SetValue('_ARRAY_PHOTO_', $arrayPhoto);
|
||||
$this->smarty->assign('photo', PATH_STATIC_CONTENT . $destDir . $destName);
|
||||
}
|
||||
}
|
||||
$this->smarty->assign('arrayPhoto', $arrayPhoto);
|
||||
}
|
||||
|
||||
public function UploadImageAction($param) {
|
||||
if (!SessionProxy::IsSetValue('_ARRAY_PHOTO_')) {
|
||||
SessionProxy::SetValue('_ARRAY_PHOTO_', array());
|
||||
}
|
||||
$arrayPhoto = SessionProxy::GetValue('_ARRAY_PHOTO_');
|
||||
//$this->SetAjaxRender();
|
||||
// $uploaddir = PATH_STATIC_CONTENT.'/upload/test/';
|
||||
// $file = $uploaddir . basename($_FILES['uploadfile']['name']);
|
||||
//Utils::ArrayDisplay($file);
|
||||
// if (move_uploaded_file($_FILES['uploadfile']['tmp_name'], $file)) {
|
||||
// echo "success";
|
||||
// } else {
|
||||
// echo "error";
|
||||
// }
|
||||
//
|
||||
$destName = md5('photo' . time());
|
||||
$destName = md5('photo' . time());
|
||||
$destNameth = "th_" . $destName . ".jpg";
|
||||
$destName .= ".jpg";
|
||||
|
||||
//$destNamea = "test.jpg";
|
||||
|
||||
$destDir = 'temp/';
|
||||
|
||||
//Utils::ArrayDisplay($_FILES);
|
||||
if (isset($_FILES['uploadfile']) && $_FILES['uploadfile']['name']) {
|
||||
//$photoSize = getimagesize(PATH_STATIC_CONTENT.$destDir.$destName);
|
||||
//Utils::ArrayDisplay(PATH_STATIC_CONTENT);
|
||||
//Utils::ArrayDisplay(PATH_STATIC_CONTENT);
|
||||
$photo = PhotoDAL::SimplePhotoUpload($_FILES['uploadfile'], $destDir);
|
||||
//Utils::ArrayDisplay(PATH_STATIC_CONTENT.$photo);
|
||||
$img_oryginal = new mImage(PATH_STATIC_CONTENT . $photo);
|
||||
//$img_oryginal->scaleProp(600, 600, 'ffffff', false, 'c', 0);
|
||||
$img_oryginal->saveToFile(PATH_STATIC_CONTENT . $destDir . $destName, 'jpg', 90, true);
|
||||
|
||||
|
||||
$normalW = 242;
|
||||
$normalH = 340;
|
||||
|
||||
// $photoSize = getimagesize(PATH_STATIC_CONTENT.$destDir.$destName);
|
||||
//
|
||||
// //Utils::ArrayDisplay($photoSize);
|
||||
//
|
||||
//// if ($photoSize[0] < $photoSize[1]) {
|
||||
//// $cropH = true;
|
||||
//// } else {
|
||||
//// $cropH = false;
|
||||
//// }
|
||||
//
|
||||
// $propW = $photoSize[0]/$normalW;
|
||||
// $propH = $photoSize[1]/$normalH;
|
||||
//
|
||||
// // Utils::ArrayDisplay($propW.' - '.$propH);
|
||||
//
|
||||
// if ($propW > $propH) {
|
||||
// $prop = $propH;
|
||||
// } else {
|
||||
// $prop = $propW;
|
||||
// }
|
||||
//
|
||||
// if ($photoSize[1] < $normalH*$prop) {
|
||||
// $photoSizeH = $normalH;
|
||||
// } else {
|
||||
// $photoSizeH = $photoSize[1];
|
||||
// }
|
||||
//
|
||||
//
|
||||
// $photoSizeH = $normalW*$prop;
|
||||
// $photoSizeW =$normalH*$prop;
|
||||
//
|
||||
//
|
||||
//Utils::ArrayDisplay($photoSizeH.'-'.$photoSizeW);
|
||||
//$img_oryginal->crop1(0, 0, $photoSizeH, $photoSizeW);
|
||||
//$img_oryginal->scaleProp($normalW, $normalH, 0, 'ffffff', false, 'c', 0);
|
||||
//$img_oryginal->
|
||||
//$img_oryginal->saveToFile(PATH_STATIC_CONTENT.$destDir.$destName, 'jpg', 90, true);
|
||||
//move_uploaded_file($_FILES['uploadfile']['tmp_name'], PATH_STATIC_CONTENT.$destDir.$_FILES['uploadfile']['name']);
|
||||
$miniW = 242;
|
||||
$miniH = 340;
|
||||
//Utils::ArrayDisplay(PATH_STATIC_CONTENT.$photo);
|
||||
|
||||
$photoSize = getimagesize(PATH_STATIC_CONTENT . $photo);
|
||||
|
||||
//$photoSize = getimagesize(PATH_STATIC_CONTENT.$destDir.$_FILES['uploadfile']['name']);
|
||||
// if ($photoSize[0] < $photoSize[1]) {
|
||||
// $cropH = true;
|
||||
// } else {
|
||||
// $cropH = false;
|
||||
// }
|
||||
|
||||
$propW = $photoSize[0] / $miniW;
|
||||
$propH = $photoSize[1] / $miniH;
|
||||
|
||||
// Utils::ArrayDisplay($propW.' - '.$propH);
|
||||
|
||||
if ($propW > $propH) {
|
||||
$prop = $propH;
|
||||
} else {
|
||||
$prop = $propW;
|
||||
}
|
||||
|
||||
if ($photoSize[1] < $miniH * $prop) {
|
||||
$photoSizeH = $miniH;
|
||||
} else {
|
||||
$photoSizeH = $photoSize[1];
|
||||
}
|
||||
|
||||
|
||||
$photoSizeH = $miniW * $prop;
|
||||
$photoSizeW = $miniH * $prop;
|
||||
$y = ($photoSize[1] - $photoSizeH) / 2;
|
||||
//Utils::ArrayDisplay($y . '=' .'('.$photoSize[1].' - '.$photoSizeH.') / 2');
|
||||
if ($y < 0) {
|
||||
$y = 0;
|
||||
}
|
||||
$y = 0;
|
||||
// Utils::ArrayDisplay($y);
|
||||
$img_oryginal->crop1(0, $y, $photoSizeH, $photoSizeW);
|
||||
$img_oryginal->scaleProp(242, 340, 0, 'ffffff', false, 'c', 0);
|
||||
//$img_oryginal->
|
||||
$img_oryginal->saveToFile(PATH_STATIC_CONTENT . $destDir . $destNameth, 'jpg', 90, true);
|
||||
//Utils::ArrayDisplay(PATH_STATIC_CONTENT.$destDir.$destNameth);
|
||||
if (is_file(PATH_STATIC_CONTENT . $photo)) {
|
||||
unlink(PATH_STATIC_CONTENT . $photo);
|
||||
}
|
||||
|
||||
$file = URL_STATIC_CONTENT . $destDir . $destNameth;
|
||||
//$fileName = $destName;
|
||||
$array = array($destName => array('normal' => $destName, 'th' => $destNameth));
|
||||
$arrayPhoto = array_merge($arrayPhoto, $array);
|
||||
SessionProxy::SetValue('_ARRAY_PHOTO_', $arrayPhoto);
|
||||
$this->smarty->assign('photo', PATH_STATIC_CONTENT . $destDir . $destName);
|
||||
//Utils::ArrayDisplay($arrayPhoto);
|
||||
$idImageGroup = ImageDAL::SaveImage(111, 'Banner', 5);
|
||||
|
||||
|
||||
if (is_file(PATH_STATIC_CONTENT . "upload/Banner/111/" . $destName)) {
|
||||
unlink(PATH_STATIC_CONTENT . "upload/Banner/111/" . $destName);
|
||||
}
|
||||
SessionProxy::ClearValue('_ARRAY_PHOTO_');
|
||||
}
|
||||
|
||||
$arrayPhoto = ImageDAL::GetResult(array('id_image_group' => 5, 'size' => 1), null, 'position ASC');
|
||||
//Utils::ArrayDisplay($arrayPhoto);
|
||||
$this->smarty->assign('arrayPhoto', $arrayPhoto);
|
||||
}
|
||||
|
||||
public function FormAction($param) {
|
||||
$this->SetAjaxRender();
|
||||
$this->addScript('jQuery/jquery-1.4.2.js', 'file', 'top', 1);
|
||||
$this->addScript('imageUpload.js', 'file', 'top', 3);
|
||||
$this->addScript('ajaxupload.3.5.js', 'file', 'top', 2);
|
||||
}
|
||||
|
||||
public function DeleteImageAction($param) {
|
||||
$this->SetAjaxRender();
|
||||
if ($_POST['photo']) {
|
||||
$obj = ImageDAL::GetResult(array('id_mf_image' => $_POST['photo']));
|
||||
|
||||
if (isset($obj[0])) {
|
||||
ImageDAL::Delete($obj[0]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->smarty->assign('photo', 'image_' . $_POST['photo']);
|
||||
}
|
||||
|
||||
public function DeleteImageBannerAction($param) {
|
||||
//$this->SetAjaxRender();
|
||||
if ($param['photo']) {
|
||||
$obj = ImageDAL::GetResult(array('id_mf_image' => $param['photo']));
|
||||
|
||||
if (isset($obj[0])) {
|
||||
ImageDAL::Delete($obj[0]);
|
||||
}
|
||||
}
|
||||
$this->AddRedirect(Router::GenerateUrl('ReloadImage', array('Image' => 'UploadImage')), 0);
|
||||
//$this->smarty->assign('photo', 'image_'.$_POST['photo']);
|
||||
}
|
||||
|
||||
public function SortImageAction($param) {
|
||||
$this->SetNoRender();
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
if ($_POST['sort']) {
|
||||
$arraySort = $_POST['sort'];
|
||||
foreach ($arraySort as $id => $sort) {
|
||||
//$obj = ImageDAL::GetResult(array('id_mf_image' => $id));
|
||||
ImageDAL::UpdateSort($id, $sort);
|
||||
}
|
||||
}
|
||||
$this->AddRedirect(Router::GenerateUrl('ReloadImage', array('Image' => 'UploadImage')), 0);
|
||||
}
|
||||
|
||||
public static function ImportProductAction() {
|
||||
|
||||
}
|
||||
|
||||
public function AddStructureAction($param) {
|
||||
if (isset($param['runSharedVariable'])) {
|
||||
$this->smarty->assign('moduleBoxId', $param['runSharedVariable']);
|
||||
$this->smarty->assign('moduleName', $param['moduleName']);
|
||||
}
|
||||
//$this->smarty->assign('arrayPhoto', $arrayFiles);
|
||||
//Utils::ArrayDisplay($param);
|
||||
}
|
||||
|
||||
public function EditStructureAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
if (isset($param['runSharedVariable'])) {
|
||||
$this->smarty->assign('moduleBoxId', $param['runSharedVariable']);
|
||||
$this->smarty->assign('moduleName', $param['moduleName']);
|
||||
}
|
||||
//Utils::ArrayDisplay($param);
|
||||
/*
|
||||
* TODO:
|
||||
* 1. Poprawić clase ImageDAL
|
||||
* 2. Dodać id struktury
|
||||
* 3.
|
||||
*
|
||||
*/
|
||||
// $arrayImage = ImageDAL::GetResult(array('id_image_group' => 1, 'size' => 2),null,'weight',null);
|
||||
// $this->smarty->assign('arrayPhoto', $arrayImage);
|
||||
// Utils::ArrayDisplay($arrayImage);
|
||||
//$this->smarty->assign('arrayPhoto', $arrayFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* preDispatch
|
||||
* @param array $param
|
||||
* @return null
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
|
||||
//$this->AddScript("jQuery/jquery-1.4.2.js");
|
||||
//$this->AddScript("ajaxupload.3.5.js");
|
||||
//$this->AddScript("UploadImage.js");
|
||||
|
||||
|
||||
|
||||
$this->RunShared('Auth', array());
|
||||
$this->Run($param);
|
||||
$this->smarty->assign('titleAdmin', 'Slideshow');
|
||||
$this->smarty->assign('structure', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* postDispatch
|
||||
* @param array $param
|
||||
* @return null
|
||||
*/
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
83
Admin/controller/IndexController.php
Normal file
83
Admin/controller/IndexController.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Strona glowna
|
||||
*
|
||||
*/
|
||||
class IndexController extends MainController implements ControllerInterface {
|
||||
|
||||
/**
|
||||
* strona glowna
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
$kat = '../temp/compile';
|
||||
$katalog = opendir($kat);
|
||||
while ($plik = readdir($katalog)) {
|
||||
if ($plik != '.' AND $plik != '..') {
|
||||
unlink($kat . '/' . $plik);
|
||||
}
|
||||
}
|
||||
$this->AddRedirect(URL_MAIN . '/Structure/', 0);
|
||||
//$this->AddRedirect(URL_MAIN . '/Calc/', 0);
|
||||
}
|
||||
|
||||
public function TestAction($param) {
|
||||
|
||||
}
|
||||
|
||||
public function ParserXmlAction($param) {
|
||||
|
||||
//ini_set($varname, $newvalue)
|
||||
$xml = simplexml_load_file(PATH_STATIC_CONTENT . "/sklepy_stacjonarne.xml");
|
||||
Utils::ArrayDisplay($xml);
|
||||
//$arrayXml = XML2Array::createArray($xml->channel);
|
||||
$k = 0;
|
||||
// foreach ($xml->channel->item as $key => $entry) {
|
||||
// //Utils::ArrayDisplay($entry);
|
||||
// $htmlString[$k]['content'] = (string) $entry->children('content', true)->encoded;
|
||||
// $htmlString[$k]['title'] = (string) $entry->title;
|
||||
// $date = $entry->pubDate;
|
||||
// $htmlString[$k]['pubDate'] = (string) $entry->children('wp', true)->post_date;
|
||||
// $htmlString[$k]['autor'] = (string) $entry->children('dc', true)->creator;
|
||||
//
|
||||
// $content = (string) $entry->children('content', true)->encoded;
|
||||
// $arrayContent = explode("<!--more-->", $content);
|
||||
// Utils::ArrayDisplay($arrayContent);
|
||||
// $htmlString[$k]['shortnote'] = nl2br($arrayContent[0]);
|
||||
// if (isset($arrayContent[1])) {
|
||||
// $htmlString[$k]['content'] = nl2br($arrayContent[1]);
|
||||
// } else {
|
||||
// $htmlString[$k]['content'] = "";
|
||||
// }
|
||||
//
|
||||
//
|
||||
// $k++;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Metoda wspolna
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
$this->smarty->assign('titleAdmin', 'Panel Administracyjny');
|
||||
// $this->RunShared('Auth');
|
||||
// $this->RunShared('Auth', array());
|
||||
// $this->smarty->assign("menuSelected", "");
|
||||
// $this->smarty->assign('activeTab', 'index');
|
||||
// $this->AddScript("formAction.js");
|
||||
// $this->Run($param);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
66
Admin/controller/LoginController.php
Normal file
66
Admin/controller/LoginController.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* $Id: LoginController.php 969 2008-07-29 13:55:14Z pawy $
|
||||
* Kontroler autoryzacji
|
||||
*
|
||||
*/
|
||||
class LoginController extends MainController implements ControllerInterface {
|
||||
/**
|
||||
* domyslna metoda
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoryzacja
|
||||
*
|
||||
*/
|
||||
public function AuthAction($param) {
|
||||
|
||||
if(isset($_REQUEST['eLogin']) && isset($_REQUEST['ePassword'])){
|
||||
$result = AuthDAL::Login($_REQUEST['eLogin'], $_REQUEST['ePassword']);
|
||||
//Utils::ArrayDisplay($_REQUEST);
|
||||
//Utils::ArrayDisplay($result);
|
||||
if($result == true){
|
||||
//$logger = LoggerManager::getLogger(__CLASS__);
|
||||
//$logger->info('Zalogowal sie uzytkownik: '.$_REQUEST['eLogin'].', z ip: '.getenv('REMOTE_ADDR').', z domeny: '.getenv('REMOTE_HOST'));
|
||||
Header("Location: ". Router::GenerateUrl('indexURL', array('Structure' => 'Index')) );
|
||||
} else {
|
||||
$this->smarty->assign("loginError", "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wylogowanie
|
||||
*
|
||||
*/
|
||||
public function LogoutAction($param) {
|
||||
SessionProxy::ClearSession();
|
||||
AuthDAL::Logout();
|
||||
|
||||
die(Header("Location: login".APPLICATION_FILE_TYPE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wspolna metoda
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
$this->smarty->assign('projectName', PROJECT_NAME);
|
||||
//session_start();
|
||||
$template = 'login.tpl';
|
||||
Registry::Remove('smartyTemplate');
|
||||
Registry::Set('smartyTemplate', $template);
|
||||
$this->smarty->assign("loginError", "");
|
||||
|
||||
}
|
||||
|
||||
public function postDispatch($param)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
236
Admin/controller/MailingController.php
Normal file
236
Admin/controller/MailingController.php
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
/**
|
||||
* $Id$
|
||||
* przypominarka
|
||||
*
|
||||
*/
|
||||
class MailingController extends ModuleController implements ControllerInterface {
|
||||
const REDIRECT_URL = "mailing.frmx";
|
||||
/**
|
||||
* Domyslna metoda
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
|
||||
//Utils::ArrayDisplay($param);
|
||||
|
||||
//$arrayAddress = MailingDAL::GetMailingAddressList(1);
|
||||
//PEJDZOWANIE
|
||||
|
||||
$countLimit = 10;
|
||||
if(isset($param['strona']) && $param['strona'] > 0 ){
|
||||
$offset = ($param['strona']-1) * $countLimit;
|
||||
$this->smarty->assign('currentPage', ($param['strona']-1)* $countLimit);
|
||||
|
||||
}
|
||||
else{
|
||||
$offset = 0;
|
||||
$this->smarty->assign('currentPage', 0);
|
||||
}
|
||||
|
||||
$this->smarty->assign('PageCount', ceil(MailingDAL::GetCountAll()/$countLimit));
|
||||
$this->RunShared('Pagination', $param);
|
||||
//AKCJE DOMY<4D>LNE
|
||||
$arrayObjMailing = MailingDAL::GetAll($offset, $countLimit);
|
||||
//Utils::ArrayDisplay($_SERVER['DOCUMENT_ROOT']);
|
||||
|
||||
|
||||
$this->smarty->assign('arrayObjMailing', $arrayObjMailing);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wysy<73>ka metoda
|
||||
*
|
||||
*/
|
||||
public function SendAction($param) {
|
||||
|
||||
|
||||
if (isset($_POST['sendEmail'])) {
|
||||
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
|
||||
$objMailing = new Mailing('', $_POST['subjet'], $_POST['content'], 0, '', 2, 0);
|
||||
MailingDAL::Save($objMailing);
|
||||
$this->smarty->assign('sendInfo', "Email zosta<74> przekazany do wysy<73>i");
|
||||
Utils::Redirect(URL_MAIN.'/index,'.self::REDIRECT_URL);
|
||||
|
||||
}
|
||||
|
||||
include("plugins/fckeditor/fckeditor_php5.php");
|
||||
$oFCKeditor = new FCKeditor('content');
|
||||
$oFCKeditor->BasePath = 'plugins/fckeditor/';
|
||||
$oFCKeditor->Value = '';
|
||||
$oFCKeditor->ToolbarSet = 'Formix';
|
||||
$oFCKeditor->Height = 400;
|
||||
$this->smarty->assign('fck', $oFCKeditor);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Podgl<67>d
|
||||
*
|
||||
*/
|
||||
public function ShowAction($param) {
|
||||
|
||||
//$arrayAddress = MailingDAL::GetMailingAddressList();
|
||||
//Utils::ArrayDisplay($arrayAddress);
|
||||
//Utils::ArrayDisplay($param);
|
||||
if (isset($param['id'])) {
|
||||
|
||||
$objMailing = MailingDAL::GetMailingById($param['id']);
|
||||
$this->smarty->assign('objMailing', $objMailing);
|
||||
}
|
||||
|
||||
// if (!isset($objMailing)) {
|
||||
// die(Header('Location: mailing'.APPLICATION_FILE_TYPE));
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function GetSendAction() {
|
||||
$logger = LoggerManager::getLogger(__CLASS__);
|
||||
$objMailing = MailingDAL::GetMailingToSend();
|
||||
//while (($objMailing = MailingDAL::GetMailingToSend())) {
|
||||
|
||||
// }
|
||||
if (is_object($objMailing)) {
|
||||
$logger = LoggerManager::getLogger(__CLASS__);
|
||||
$limit = $objMailing->GetLastSend() + 50;
|
||||
$mailList = array();
|
||||
$logger->info("limit: $limit ".$objMailing->GetLastSend());
|
||||
$mailList = MailingDAL::GetMailingAddressList(2, $objMailing->GetLastSend(), 50);
|
||||
MailingDAL::UpdateLastSend($objMailing->GetId(), $limit);
|
||||
//Utils::ArrayDisplay($mailList);
|
||||
|
||||
// pobiera z tabeli user (jezeli taka istnije w tym przypadku nie potrzebna)
|
||||
// if (!is_array($mailList) || count($mailList) < 50 && $objMailing->GetType() == 1) {
|
||||
// MailingDAL::UpdateLastSend($objMailing->GetId(), 0);
|
||||
// MailingDAL::UpdateType($objMailing->GetId());
|
||||
//
|
||||
// }
|
||||
|
||||
if (!is_array($mailList) || count($mailList) < 50 && $objMailing->GetType() == 2) {
|
||||
MailingDAL::UpdateLastSend($objMailing->GetId(), 0);
|
||||
MailingDAL::SetExecuted($objMailing->GetId());
|
||||
}
|
||||
|
||||
|
||||
//$this->smarty->assign('content', $objMailing->GetText());
|
||||
//$txtmessage = $this->smarty->fetch('MailTxt.tpl');
|
||||
//Utils::ArrayDisplay($mailList);
|
||||
|
||||
foreach ($mailList as $key => $arrayPackage) {
|
||||
foreach ($arrayPackage as $keyPackege => $value) {
|
||||
$subjet = " DB Druk - ".$objMailing->GetTitle();
|
||||
$mail = new PHPMailer();
|
||||
$mail -> CharSet = "utf-8";
|
||||
$mail -> Subject = $subjet;
|
||||
$mail -> SMTPAuth = true;
|
||||
$mail -> Mailer = 'smtp';
|
||||
$mail -> Host = "dbdruk.formix.eu";
|
||||
$mail -> Port = 25;
|
||||
$mail -> Priority = 3;
|
||||
$mail ->IsHTML(true);
|
||||
//$mail -> ConfirmReadingTo = "wino@wino.formix.eu";
|
||||
$mail ->From = "smtp@dbdruk.formix.eu";
|
||||
$mail -> FromName = "DB Druk";
|
||||
$mail -> Username = "smtp@dbdruk.formix.eu";
|
||||
$mail -> Password = "smtp1234";
|
||||
//$mail->AddAddress('maciek@formix.pl', 'Maciej Kloch');
|
||||
$mail->AddAddress($value['email'], $value['name']);
|
||||
|
||||
$mail -> AddBCC("maciek@formix.pl", "Mailing - dbdruk.pl ".$value['email']."- ".$value['name']." ".$key."-".$keyPackege);
|
||||
$mail -> Body = $objMailing->GetText();
|
||||
$mail -> Send();
|
||||
}
|
||||
//sleep(2);
|
||||
}
|
||||
//sleep(25);
|
||||
}
|
||||
Utils::Redirect(URL_MAIN.'/index,'.self::REDIRECT_URL);
|
||||
}
|
||||
|
||||
public function ListAction($param) {
|
||||
//PEJDZOWANIE
|
||||
|
||||
$countLimit = 10;
|
||||
if(isset($param['strona']) && $param['strona'] > 0 ){
|
||||
$offset = ($param['strona']-1) * $countLimit;
|
||||
$this->smarty->assign('currentPage', ($param['strona']-1)* $countLimit);
|
||||
|
||||
}
|
||||
else{
|
||||
$offset = 0;
|
||||
$this->smarty->assign('currentPage', 0);
|
||||
}
|
||||
|
||||
$this->smarty->assign('PageCount', ceil(MailingDAL::GetCountAllEmail()/$countLimit));
|
||||
$this->RunShared('Pagination', $param);
|
||||
//AKCJE DOMY<4D>LNE
|
||||
$arrayEmail = MailingDAL::GetAllEmail($offset, $countLimit);
|
||||
//Utils::ArrayDisplay($arrayEmail);
|
||||
|
||||
|
||||
$this->smarty->assign('arrayEmail', $arrayEmail);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* usuwanie emial z list mailingowej
|
||||
*
|
||||
*/
|
||||
public function DeleteAction($param) {
|
||||
|
||||
$logger = LoggerManager::getLogger(__CLASS__);
|
||||
|
||||
//$idCustomer = SessionProxy::GetValue(EnumSessionValue::IDCUSTOMER);
|
||||
|
||||
if(isset($param['id'])) {
|
||||
$id=$param['id'];
|
||||
} else{
|
||||
$id = null;
|
||||
}
|
||||
|
||||
if($id) {
|
||||
MailingDAL::Delete($id);
|
||||
|
||||
|
||||
die(Header('Location: list,mailing'.APPLICATION_FILE_TYPE));
|
||||
if (Pat) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Metoda wspolna
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
$this->Run($param);
|
||||
$this->RunShared('Mailing');
|
||||
$this->smarty->assign('titleAdmin', 'Mailing');
|
||||
//$this->smarty->assign('showIcon', false);
|
||||
if($this->IsUser()==false) {
|
||||
$this->AddRedirect(URL_MAIN.'/Login.frmx', 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
1257
Admin/controller/MainSiteController.php
Normal file
1257
Admin/controller/MainSiteController.php
Normal file
File diff suppressed because it is too large
Load Diff
324
Admin/controller/MapsController.php
Normal file
324
Admin/controller/MapsController.php
Normal file
@@ -0,0 +1,324 @@
|
||||
<?
|
||||
class MapsController extends MainController implements ControllerInterface
|
||||
{
|
||||
|
||||
const ARRAY_MAPS_TYPE = array(1=> 'hean', 2=> 'hebe');
|
||||
|
||||
|
||||
public function IndexAction($param){
|
||||
|
||||
|
||||
$dalData = FkMapsDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array());
|
||||
// $dalData->setLimit(10);
|
||||
$dalData->setSortBy('city');
|
||||
|
||||
|
||||
$arrayMaps = FkMapsDAL::GetResult($dalData);
|
||||
//Utils::ArrayDisplay($arrayMaps);
|
||||
$this->smarty->assign('arrayMapsType', self::ARRAY_MAPS_TYPE);
|
||||
|
||||
}
|
||||
public function IndexStructureAction($param){
|
||||
$this->smarty->assign('arrayMapsType', self::ARRAY_MAPS_TYPE);
|
||||
$this->smarty->assign('icon', true);
|
||||
//Utils::ArrayDisplay($param);
|
||||
if (isset($param['runSharedVariable'])) {
|
||||
$this->smarty->assign('moduleBoxId', $param['runSharedVariable']);
|
||||
$this->smarty->assign('moduleName', $param['moduleName']);
|
||||
}
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$data = array();
|
||||
if (isset($param['id'])) {
|
||||
$data = array('fk_maps.id_structure' => $param['id'], 'lang' => $lang);
|
||||
|
||||
} else {
|
||||
$this->smarty->assign('add', true);
|
||||
$this->smarty->assign('icon', false);
|
||||
}
|
||||
|
||||
$dalData = FkMapsDAL::GetDalDataObj();
|
||||
$dalData->setCondition($data);
|
||||
$dalData->setSortBy('weight');
|
||||
|
||||
|
||||
$arrayMaps = FkMapsDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObj', $arrayMaps);
|
||||
//Utils::ArrayDisplay($arrayMaps);
|
||||
|
||||
}
|
||||
|
||||
public function EditStructureAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$dalData = FkMapsDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $lang, 'id_structure' => $param['id']));
|
||||
$dalData->setSortBy('weight');
|
||||
|
||||
|
||||
$arrayMaps = FkMapsDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObj', $arrayMaps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Akcja dodawania
|
||||
*
|
||||
* @param <type> $param
|
||||
*/
|
||||
public function AddAction($param) {
|
||||
|
||||
|
||||
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$idStructure = SessionProxy::GetValue('idStructure');
|
||||
if (!$idStructure) {
|
||||
$this->AddRedirect(Router::GenerateUrl('IndexStructure', array('Structure' => 'Index')), 0);
|
||||
}
|
||||
$this->smarty->assign('idStructure', $idStructure);
|
||||
//$idCategory = SessionProxy::GetValue('idCategory');
|
||||
// $idCategory = $idStructure;
|
||||
$arrayMapsType = Utils::GetArrayList('fk_maps_category', 'id_fk_maps_category','name');
|
||||
$this->smarty->assign('arrayMapsType', $arrayMapsType);
|
||||
|
||||
$objMaps = FkMapsDAL::GetEmptyObj();
|
||||
|
||||
|
||||
if(Request::IsPost()) {
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
//$validator->IsDate('datepublication', 'Pole data publikacji musi zostać wypełnione.');
|
||||
//$validator->IsEmpty('description', 'Pole opis musi zostać wypełnione.');
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
//$data['timepublication'] = $data['timepublication'] ? $data['timepublication'] : '00';
|
||||
|
||||
|
||||
// $objMaps->SetDate(Utils::GetNowDate());
|
||||
// //$objMaps->SetDatePublication($data['datepublication']." ".$data['timepublication'].":00:00");
|
||||
// $objMaps->SetDatePublication(Utils::GetNowDate());
|
||||
$objMaps->SetName($data['name']);
|
||||
$objMaps->SetWeight($data['weight']);
|
||||
$objMaps->SetCity($data['city']);
|
||||
$objMaps->SetAddress($data['address']);
|
||||
$objMaps->SetLng($data['lng']);
|
||||
$objMaps->SetLat($data['lat']);
|
||||
$objMaps->setPublication($publication);
|
||||
// $objMaps->SetType($data['type']);
|
||||
$objMaps->SetIdStructure($idStructure);
|
||||
$objMaps->SetLang($lang);
|
||||
|
||||
// $objMaps->SetDescription($data['description']);
|
||||
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
|
||||
|
||||
|
||||
$iid = FkMapsDAL::Save($objMaps);
|
||||
|
||||
|
||||
$this->smarty->assign('iid', $iid);
|
||||
//$this->AddRedirect(Router::GenerateUrl('indexMaps', array('Maps'=> 'Index')), 0);
|
||||
$this->AddRedirect(Router::GenerateUrl('editStructure', array('id' => $idStructure)), 0);
|
||||
|
||||
} else {
|
||||
//$this->content=$this->FormatAjaxOutput($out, $param);
|
||||
//Utils::ArrayDisplay($out);
|
||||
|
||||
$this->smarty->assign('objMaps',$objMaps);
|
||||
//$datePublished = explode(" ",$objMaps->GetDatePublication());
|
||||
|
||||
//
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Akcja dodawania
|
||||
*
|
||||
* @param <type> $param
|
||||
*/
|
||||
public function EditAction($param) {
|
||||
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$idStructure = SessionProxy::GetValue('idStructure');
|
||||
$this->smarty->assign('idStructure', $idStructure);
|
||||
//$idCategory = SessionProxy::GetValue('idCategory');
|
||||
// $idCategory = $idStructure;
|
||||
//$arrayMapsType = Utils::GetArrayList('fk_maps_type', 'name', $lang);
|
||||
//$this->smarty->assign('arrayMapsType', $arrayMapsType);
|
||||
|
||||
//$objMaps = FkMapsDAL::GetEmptyObj();
|
||||
$objMaps = FkMapsDAL::GetById($param['idMaps'], $lang);
|
||||
|
||||
|
||||
if(Request::IsPost()) {
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
//$validator->IsDate('datepublication', 'Pole data publikacji musi zostać wypełnione.');
|
||||
//$validator->IsEmpty('description', 'Pole opis musi zostać wypełnione.');
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
|
||||
$objMaps->SetName($data['name']);
|
||||
$objMaps->SetWeight($data['weight']);
|
||||
$objMaps->SetCity($data['city']);
|
||||
$objMaps->SetAddress($data['address']);
|
||||
$objMaps->SetLng($data['lng']);
|
||||
$objMaps->SetLat($data['lat']);
|
||||
$objMaps->setPublication($publication);
|
||||
// $objMaps->SetType($data['type']);
|
||||
$objMaps->SetIdStructure($idStructure);
|
||||
$objMaps->SetLang($lang);
|
||||
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
$iid = FkMapsDAL::Save($objMaps);
|
||||
|
||||
|
||||
$this->smarty->assign('iid', $iid);
|
||||
//$this->AddRedirect(Router::GenerateUrl('indexMaps', array('Maps'=> 'Index')), 0);
|
||||
$this->AddRedirect(Router::GenerateUrl('editStructure', array('id' => $idStructure)), 0);
|
||||
|
||||
} else {
|
||||
//$this->content=$this->FormatAjaxOutput($out, $param);
|
||||
//Utils::ArrayDisplay($out);
|
||||
|
||||
$this->smarty->assign('objMaps',$objMaps);
|
||||
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->smarty->assign('objMaps', $objMaps);
|
||||
}
|
||||
|
||||
public function DeleteAction($param) {
|
||||
$idStructure = SessionProxy::GetValue('idStructure');
|
||||
//$logger = LoggerManager::getLogger(__CLASS__);
|
||||
|
||||
$idMaps = $param['idMaps'];
|
||||
if ($idMaps) {
|
||||
try {
|
||||
$objMaps = FkMapsDAL::GetById($idMaps);
|
||||
|
||||
$dalData = FkMapsDAL::GetDalDataObj();
|
||||
|
||||
$dalData->setId($idMaps);
|
||||
$dalData->setObj($objMaps);
|
||||
FkMapsDAL::Delete($dalData);
|
||||
|
||||
} catch (Exception $e) {
|
||||
//Utils::ArrayDisplay($e);
|
||||
$logger->error('bład usunięcia elementu o id: '.$idMaps);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->AddRedirect(Router::GenerateUrl('editStructure', array('id' => $idStructure)), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Import from xml
|
||||
*
|
||||
* TODO: Upload file.
|
||||
*
|
||||
*/
|
||||
public function ImportXmlAction($param) {
|
||||
|
||||
//ini_set($varname, $newvalue)
|
||||
$xml = simplexml_load_file(PATH_STATIC_CONTENT . "/sklepy_stacjonarne-ania.xml");
|
||||
// Utils::ArrayDisplay($xml->marker);
|
||||
//$arrayXml = XML2Array::createArray($xml->channel);
|
||||
$k = 0;
|
||||
foreach ($xml as $key => $entry) {
|
||||
|
||||
Utils::ArrayDisplay($entry->attributes('id'));
|
||||
$arrayAtrib = $entry->attributes();
|
||||
|
||||
|
||||
$objMaps = FkMapsDAL::GetEmptyObj();
|
||||
$objMaps->setName((string)$arrayAtrib['name']);
|
||||
$objMaps->SetWeight((string)$arrayAtrib['id']);
|
||||
$objMaps->SetCity((string)$arrayAtrib['city']);
|
||||
$objMaps->SetAddress((string)$arrayAtrib['address']);
|
||||
$objMaps->SetLng((string)$arrayAtrib['lng']);
|
||||
$objMaps->SetLat((string)$arrayAtrib['lat']);
|
||||
$objMaps->setPublication(1);
|
||||
$objMaps->setType(1);
|
||||
$objMaps->setIdCategory(1);
|
||||
// $objMaps->SetType($data['type']);
|
||||
$objMaps->SetIdStructure(3);
|
||||
$objMaps->SetLang('pl');
|
||||
|
||||
Utils::ArrayDisplay($objMaps);
|
||||
//$iid = FkMapsDAL::Save($objMaps);
|
||||
$k++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* preDispatch
|
||||
* @param array $param
|
||||
* @return null
|
||||
*/
|
||||
public function preDispatch($param){
|
||||
$this->Run($param);
|
||||
$this->AddScript('dropDown.js');
|
||||
$this->AddScript('structure.js');
|
||||
$this->AddScript('Dosia.js');
|
||||
$this->AddScript('Link.js');
|
||||
$this->AddScript('drag-drop-folder-tree.js');
|
||||
// //$this->AddScript('Validator.js');
|
||||
$this->AddScript('calendar.js');
|
||||
|
||||
$this->RunShared('Auth', array());
|
||||
|
||||
$this->RunShared('Structure', $param);
|
||||
$this->smarty->assign('arrayMapsType', self::ARRAY_MAPS_TYPE);
|
||||
$this->smarty->assign('idStucture', SessionProxy::GetValue('idStructure'));
|
||||
|
||||
$this->smarty->assign('lang', 'pl');
|
||||
$this->smarty->assign('titleAdmin', 'Pliki');
|
||||
$this->smarty->assign('activeTab', 'index');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* postDispatch
|
||||
* @param array $param
|
||||
* @return null
|
||||
*/
|
||||
public function postDispatch($param){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
540
Admin/controller/ProductAttributeController.php
Normal file
540
Admin/controller/ProductAttributeController.php
Normal file
@@ -0,0 +1,540 @@
|
||||
<?php
|
||||
/**
|
||||
* Produkty
|
||||
*
|
||||
*
|
||||
*/
|
||||
class ProductAttributeController extends MainController implements ControllerInterface {
|
||||
|
||||
|
||||
const AVATAR_DEST_DIR = '/upload/Product';
|
||||
const AVATAR_TEMP_DIR = '/upload/temp';
|
||||
const NO_PHOTO_IMG_BIG = "image/Admin/cropperNoPhotoBig.gif";
|
||||
const NO_PHOTO_IMG_SMALL = "image/Admin/przekatne.gif";
|
||||
const MAX_AVATAR_FILE_SIZE = 5; //Rozmiar w mb
|
||||
const CROPPER_BIG_PHOTO_MAX_WIDTH = 800;
|
||||
const CROPPER_BIG_PHOTO_MAX_HEIGHT = 800;
|
||||
const PHOTO_WIDTH = 800;
|
||||
const PHOTO_HEIGHT = 600;
|
||||
|
||||
const IMAGE_MINI_WIDTH = 240;
|
||||
const IMAGE_MINI_HEIGHT = 180;
|
||||
const IMAGE_NORMAL_WIDTH = 800;
|
||||
const IMAGE_NORMAL_HEIGHT = 600;
|
||||
|
||||
|
||||
public function IndexAction($param) {
|
||||
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$arrayObjProductAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
|
||||
// $param['runSharedVariable'] = 'linkedAttribute';
|
||||
// $this->RunModuleController( 'ProductAttributeController', 'LinkedAttribute', $param, true);
|
||||
//
|
||||
// $param['runSharedVariable'] = 'unlinkedAttribute';
|
||||
// $this->RunModuleController( 'ProductAttributeController', 'UnlinkedAttribute', $param, true);
|
||||
|
||||
$this->smarty->assign('arrayObjProductAttribute', $arrayObjProductAttribute);
|
||||
//Utils::ArrayDisplay($arrayObjProductAttribute);
|
||||
}
|
||||
|
||||
// public function UpdateLangAttrAction($param) {
|
||||
//
|
||||
// $dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
// $dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
// $dalData->setCondition(array('lang' => 'pl'));
|
||||
// $arrayObjProductAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
//
|
||||
// //Utils::ArrayDisplay($arrayObjProductAttribute);
|
||||
//
|
||||
// foreach ($arrayObjProductAttribute as $objProductAttribute) {
|
||||
// //Utils::ArrayDisplay($objProductAttribute->GetDescriptionObj());
|
||||
// $objDesc = $objProductAttribute->GetDescriptionObj();
|
||||
// foreach (Router::$arrayLang as $lang) {
|
||||
// if ($lang != 'pl') {
|
||||
//
|
||||
// $objDesc->setLang($lang);
|
||||
// $objDesc->setId('-1');
|
||||
// Utils::ArrayDisplay($objDesc);
|
||||
// MfProductAttributeDescriptionDAL::Save($objDesc);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public function UpdateLangCatAction($param) {
|
||||
//
|
||||
// $dalData = MfProductCategoryDAL::GetDalDataObj();
|
||||
// $dalData->setJoin(array('MfProductCategoryDescription' => ' LEFT JOIN mf_product_category_description ON mf_product_category.id_mf_product_category=mf_product_category_description.id_mf_product_category '));
|
||||
// $dalData->setCondition(array('lang' => 'pl'));
|
||||
// $arrayObjProductCategory = MfProductCategoryDAL::GetResult($dalData);
|
||||
//
|
||||
// //Utils::ArrayDisplay($arrayObjProductAttribute);
|
||||
//
|
||||
// foreach ($arrayObjProductCategory as $objProductCategory) {
|
||||
// //Utils::ArrayDisplay($objProductAttribute->GetDescriptionObj());
|
||||
// $objDesc = $objProductCategory->GetDescriptionObj();
|
||||
// foreach (Router::$arrayLang as $lang) {
|
||||
// if ($lang != 'pl') {
|
||||
//
|
||||
// $objDesc->setLang($lang);
|
||||
// $objDesc->setId('-1');
|
||||
// Utils::ArrayDisplay($objDesc);
|
||||
// MfProductCategoryDescriptionDAL::Save($objDesc);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
public function LinkedAttributeAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
if (isset($param['idAttribute'])) {
|
||||
$idsAttribute = MfProductLinkDAL::GetIdStringDestinaion('mf_product_attribute', 'mf_product_attribute', $param['idAttribute'], $param['lang']);
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idsAttribute.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
} else {
|
||||
$this->smarty->assign('arrayObjAttribute', array());
|
||||
$this->smarty->assign('clikAttribute', true);
|
||||
}
|
||||
}
|
||||
|
||||
public function UnlinkedAttributeAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
if (isset($param['idAttribute'])) {
|
||||
$idsAttribute = MfProductLinkDAL::GetIdStringDestinaion('mf_product_attribute', 'mf_product_attribute', $param['idAttribute'], $param['lang']);
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute NOT IN ('.$idsAttribute.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
} else {
|
||||
$this->smarty->assign('arrayObjAttribute', array());
|
||||
$this->smarty->assign('clikAttribute', true);
|
||||
}
|
||||
}
|
||||
|
||||
public function IndexStructureAction($param) {
|
||||
|
||||
$idAttribute = SessionProxy::GetValue('idAttribute');
|
||||
$this->smarty->assign('idAttribute', $idAttribute);
|
||||
|
||||
$idsProduct = MfProductLinkDAL::GetIdStringDestinaion('mf_product_attribute', 'mf_product',$idAttribute, $param['lang']);
|
||||
|
||||
$dalData = MfProductDAL::GetDalDataObj();
|
||||
$dalData->setJoin(array('MfProductDescription' => ' LEFT JOIN mf_product_description ON mf_product.id_mf_product=mf_product_description.id_mf_product '));
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
//Utils::ArrayDisplay('ss'.$idsProduct);
|
||||
$dalData->addCondition(' ', 'mf_product.id_mf_product IN (' .$idsProduct. ') ', ' ');
|
||||
$arrayObj = MfProductDAL::GetResult($dalData);
|
||||
|
||||
$this->smarty->assign('arrayObj', $arrayObj);
|
||||
if (isset($param['methodToRun']) && $param['methodToRun'] == 'Add') {
|
||||
$this->smarty->assign('add', true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function AddAction($param) {
|
||||
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
// $dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idsAttribute.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
//$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_attribute', $idAttribute, 'mf_product_attribute');
|
||||
//Utils::ArrayDisplay($arrayObjAttribue);
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('arrayObjAttributeLinked', array());
|
||||
$objAttributeProduct = MfProductAttributeDAL::GetEmptyObj();
|
||||
|
||||
if (Request::GetPost('doAttributeAdd')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name_pl', 'Pole nazwa musi zostać wypełnione.');
|
||||
//$validator->IsEmpty('name_en', 'Pole nazwa musi zostać wypełnione.');
|
||||
//$validator->IsEmpty('name_ru', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
//$objProduct = new MfProduct();
|
||||
//$objAttributeProduct->setDate($data['datepublication']." ".$data['timepublication'].":00:00");
|
||||
$objAttributeProduct->setDate("0000-00-00");
|
||||
$objAttributeProduct->setPublication($publication);
|
||||
$objAttributeProductDesc = new MfProductAttributeDescription();
|
||||
$objAttributeProductDescEn = new MfProductAttributeDescription();
|
||||
$objAttributeProductDescRu = new MfProductAttributeDescription();
|
||||
$objAttributeProductDesc->setLang('pl');
|
||||
$objAttributeProductDesc->setDescription($data['name_pl']);
|
||||
$objAttributeProductDescEn->setLang('en');
|
||||
$objAttributeProductDescEn->setDescription($data['name_en']);
|
||||
$objAttributeProductDescRu->setLang('ru');
|
||||
$objAttributeProductDescRu->setDescription($data['name_ru']);
|
||||
|
||||
//$arrayObjAttributeWithValue = array();
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjAttribute);
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
|
||||
//Utils::ArrayDisplay($objAttributeProductDesc);
|
||||
//Utils::ArrayDisplay($objAttributeProductDescEn);
|
||||
//Utils::ArrayDisplay($objAttributeProductDescRu);
|
||||
$idAttributeProduct = MfProductAttributeDAL::Save($objAttributeProduct);
|
||||
$objAttributeProductDesc->setIdMfProductAttribute($idAttributeProduct);
|
||||
$objAttributeProductDescEn->setIdMfProductAttribute($idAttributeProduct);
|
||||
$objAttributeProductDescRu->setIdMfProductAttribute($idAttributeProduct);
|
||||
MfProductAttributeDescriptionDAL::Save($objAttributeProductDesc);
|
||||
MfProductAttributeDescriptionDAL::Save($objAttributeProductDescEn);
|
||||
MfProductAttributeDescriptionDAL::Save($objAttributeProductDescRu);
|
||||
|
||||
// foreach ($data['attr'] as $attrKey => $attrId ) {
|
||||
// $objMfProductLink = new MfProductLink();
|
||||
// $objMfProductLink->setDestinationType('mf_product_attribute');
|
||||
// $objMfProductLink->setSourceType('mf_product_attribute');
|
||||
// $objMfProductLink->setIdDestination($attrId);
|
||||
// $objMfProductLink->setIdSource($idAttributeProduct);
|
||||
// $objMfProductLink->setLang($param['lang']);
|
||||
// $objMfProductLink->setPublication(1);
|
||||
// MfProductLinkDAL::Save($objMfProductLink);
|
||||
// }
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editAttribute', array('ProductAttribute' => 'index')));
|
||||
} else {
|
||||
|
||||
// if (isset($data['attr'])) {
|
||||
// $idAttrLinked = implode(', ',$data['attr']);
|
||||
// } else {
|
||||
// $idAttrLinked = '-1';
|
||||
// }
|
||||
// $dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
// $dalData->setCondition(array('lang' => $param['lang']));
|
||||
// $dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idAttrLinked.') ', ' ');
|
||||
// $dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
//
|
||||
// //Utils::ArrayDisplay($dalData);
|
||||
// $arrayObjAttributeLinked = MfProductAttributeDAL::GetResult($dalData);
|
||||
// //$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_attribute', $idAttribute, 'mf_product_attribute');
|
||||
// //Utils::ArrayDisplay($arrayObjAttributeLinked);
|
||||
//
|
||||
// $dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
// $dalData->setCondition(array('lang' => $param['lang']));
|
||||
// $dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute NOT IN ('.$idAttrLinked.') ', ' ');
|
||||
// $dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
//
|
||||
// //Utils::ArrayDisplay($dalData);
|
||||
// $arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
//
|
||||
// $this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
// $this->smarty->assign('arrayObjAttributeLinked', $arrayObjAttributeLinked);
|
||||
|
||||
|
||||
$objAttributeProduct->SetDescriptionObj($objAttributeProductDesc);
|
||||
$this->smarty->assign('objAttributeProductDesc',$objAttributeProductDesc);
|
||||
$this->smarty->assign('objAttributeProductDescRu',$objAttributeProductDescRu);
|
||||
$this->smarty->assign('objAttributeProductDescEn',$objAttributeProductDescEn);
|
||||
$this->smarty->assign('objAttributeProduct',$objAttributeProduct);
|
||||
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
|
||||
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function EditAction($param) {
|
||||
|
||||
|
||||
// $idsAttribute = MfProductLinkDAL::GetIdStringDestinaion('mf_product_attribute', 'mf_product_attribute', $param['id'], $param['lang']);
|
||||
// $dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
// $dalData->setCondition(array('lang' => $param['lang']));
|
||||
// $dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute NOT IN ('.$idsAttribute.') ', ' ');
|
||||
// $dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
//
|
||||
// //Utils::ArrayDisplay($dalData);
|
||||
// $arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
//
|
||||
// $dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
// $dalData->setCondition(array('lang' => $param['lang']));
|
||||
// $dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idsAttribute.') ', ' ');
|
||||
// $dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
//
|
||||
// //Utils::ArrayDisplay($dalData);
|
||||
// $arrayObjAttributeLinked = MfProductAttributeDAL::GetResult($dalData);
|
||||
// //$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_attribute', $idAttribute, 'mf_product_attribute');
|
||||
// //Utils::ArrayDisplay($arrayObjAttribue);
|
||||
// $this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
// $this->smarty->assign('arrayObjAttributeLinked', $arrayObjAttributeLinked);
|
||||
$objAttributeProduct = MfProductAttributeDAL::GetById($param['id'], 'pl');
|
||||
$objAttributeProductRu = MfProductAttributeDAL::GetById($param['id'], 'ru');
|
||||
$objAttributeProductEn = MfProductAttributeDAL::GetById($param['id'], 'en');
|
||||
//$objAttributeProduct->setLang('pl');
|
||||
$this->smarty->assign('objAttributeProduct', $objAttributeProduct);
|
||||
$this->smarty->assign('objAttributeProductDesc',$objAttributeProduct->getDescriptionObj());
|
||||
//$objAttributeProduct->setLang('en');
|
||||
$this->smarty->assign('objAttributeProductDescRu',$objAttributeProductRu->getDescriptionObj());
|
||||
//$objAttributeProduct->setLang('ru');
|
||||
$this->smarty->assign('objAttributeProductDescEn',$objAttributeProductEn->getDescriptionObj());
|
||||
|
||||
if (Request::GetPost('doAttributeEdit')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name_pl', 'Pole nazwa musi zostać wypełnione.');
|
||||
//$validator->IsEmpty('name_en', 'Pole nazwa musi zostać wypełnione.');
|
||||
//$validator->IsEmpty('name_ru', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
//$objProduct = new MfProduct();
|
||||
//$objAttributeProduct->setDate($data['datepublication']." ".$data['timepublication'].":00:00");
|
||||
$objAttributeProduct->setDate("0000-00-00");
|
||||
$objAttributeProduct->setPublication($publication);
|
||||
$objAttributeProductDesc = $objAttributeProduct->getDescriptionObj();
|
||||
$objAttributeProductDescEn = $objAttributeProductEn->getDescriptionObj();
|
||||
$objAttributeProductDescRu = $objAttributeProductRu->getDescriptionObj();
|
||||
|
||||
//$objAttributeProductDesc->setDatePublication("0000-00-00 00:00:00");
|
||||
$objAttributeProductDesc->setLang('pl');
|
||||
$objAttributeProductDesc->setDescription($data['name_pl']);
|
||||
$objAttributeProductDescEn->setLang('en');
|
||||
$objAttributeProductDescEn->setDescription($data['name_en']);
|
||||
$objAttributeProductDescRu->setLang('ru');
|
||||
$objAttributeProductDescRu->setDescription($data['name_ru']);
|
||||
$objAttributeProduct->setLang('pl');
|
||||
//$arrayObjAttributeWithValue = array();
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjAttribute);
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
//Utils::ArrayDisplay($objAttributeProductDesc);
|
||||
//Utils::ArrayDisplay($objAttributeProductDescEn);
|
||||
//Utils::ArrayDisplay($objAttributeProductDescRu);
|
||||
$idAttributeProduct = MfProductAttributeDAL::Save($objAttributeProduct);
|
||||
$objAttributeProductDesc->setIdMfProductAttribute($idAttributeProduct);
|
||||
$objAttributeProductDescEn->setIdMfProductAttribute($idAttributeProduct);
|
||||
$objAttributeProductDescRu->setIdMfProductAttribute($idAttributeProduct);
|
||||
MfProductAttributeDescriptionDAL::Save($objAttributeProductDesc);
|
||||
MfProductAttributeDescriptionDAL::Save($objAttributeProductDescEn);
|
||||
MfProductAttributeDescriptionDAL::Save($objAttributeProductDescRu);
|
||||
|
||||
|
||||
// MfProductLinkDAL::DeleteFromLink($idAttributeProduct, 'mf_product_attribute', null, 'mf_product_attribute');
|
||||
//
|
||||
// foreach ($data['attr'] as $attrKey => $attrId ) {
|
||||
// $objMfProductLink = new MfProductLink();
|
||||
// $objMfProductLink->setDestinationType('mf_product_attribute');
|
||||
// $objMfProductLink->setSourceType('mf_product_attribute');
|
||||
// $objMfProductLink->setIdDestination($attrId);
|
||||
// $objMfProductLink->setIdSource($idAttributeProduct);
|
||||
// $objMfProductLink->setLang($param['lang']);
|
||||
// $objMfProductLink->setPublication(1);
|
||||
// //Utils::ArrayDisplay($objMfProductLink);
|
||||
// MfProductLinkDAL::Save($objMfProductLink);
|
||||
// }
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editAttribute', array('ProductAttribute' => 'index')));
|
||||
} else {
|
||||
|
||||
// if (isset($data['attr'])) {
|
||||
// $idAttrLinked = implode(', ',$data['attr']);
|
||||
// } else {
|
||||
// $idAttrLinked = '-1';
|
||||
// }
|
||||
// $dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
// $dalData->setCondition(array('lang' => $param['lang']));
|
||||
// $dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idAttrLinked.') ', ' ');
|
||||
// $dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
//
|
||||
// //Utils::ArrayDisplay($dalData);
|
||||
// $arrayObjAttributeLinked = MfProductAttributeDAL::GetResult($dalData);
|
||||
// //$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_attribute', $idAttribute, 'mf_product_attribute');
|
||||
// //Utils::ArrayDisplay($arrayObjAttributeLinked);
|
||||
//
|
||||
// $dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
// $dalData->setCondition(array('lang' => $param['lang']));
|
||||
// $dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute NOT IN ('.$idAttrLinked.') ', ' ');
|
||||
// $dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
//
|
||||
// //Utils::ArrayDisplay($dalData);
|
||||
// $arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
//
|
||||
// $this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
// $this->smarty->assign('arrayObjAttributeLinked', $arrayObjAttributeLinked);
|
||||
//
|
||||
|
||||
$objAttributeProduct->SetDescriptionObj($objAttributeProductDesc);
|
||||
$this->smarty->assign('objAttributeProduct',$objAttributeProduct);
|
||||
|
||||
$this->smarty->assign('objAttributeProductDesc',$objAttributeProductDesc);
|
||||
$this->smarty->assign('objAttributeProductDescRu',$objAttributeProductDescRu);
|
||||
$this->smarty->assign('objAttributeProductDescEn',$objAttributeProductDescEn);
|
||||
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
|
||||
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function AjaxAddLinkAttrAction($param) {
|
||||
//$array
|
||||
}
|
||||
|
||||
public function DeleteAction($param) {
|
||||
$isLinked = MfProductLinkDAL::IsLinked(null, 'mf_product_category', $param['id'], 'mf_product_attribute');
|
||||
$delete = true;
|
||||
$error = '';
|
||||
if ($isLinked > 0 ) {
|
||||
$delete = false;
|
||||
}
|
||||
|
||||
$arrayLang = (Router::$arrayLang);
|
||||
unset($arrayLang[$param['lang']]);
|
||||
$langString = implode(',', $arrayLang);
|
||||
|
||||
$isLang = MfProductAttributeDAL::CheakDescLang($param['id'], $param['lang']);
|
||||
|
||||
// if ($isLang) {
|
||||
// $delete = false;
|
||||
// }
|
||||
|
||||
if ($delete) {
|
||||
|
||||
foreach (Router::$arrayLang as $lang) {
|
||||
$objAttribute = MfProductAttributeDAL::GetById($param['id'], $lang);
|
||||
$objAttributeDesc = $objAttribute->getDescriptionObj();
|
||||
$dalDataDesc = MfProductAttributeDescriptionDAL::GetDalDataObj();
|
||||
$dalDataDesc->setObj($objAttributeDesc);
|
||||
MfProductAttributeDescriptionDAL::Delete($dalDataDesc);
|
||||
}
|
||||
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setObj($objAttribute);
|
||||
MfProductAttributeDAL::Delete($dalData);
|
||||
$this->AddRedirectInfo('Element został usunięty', 'ok', Router::GenerateUrl('editAttribute', array('ProductAttribute' => 'Index')));
|
||||
} else {
|
||||
if ($isLinked) {
|
||||
$error .= 'Parametr jest powiązany z kategorią.';
|
||||
}
|
||||
// if ($isLang) {
|
||||
// $error .= $error ? '<br/><br/>' : '';
|
||||
// $error .= 'Parametr posiada wersję jezykową';
|
||||
// }
|
||||
$this->AddRedirectInfo($error, 'error', Router::GenerateUrl('editAttribute', array('ProductAttribute' => 'Index')));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wspolna metoda
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
|
||||
|
||||
$this->RunShared('Auth', $param);
|
||||
$this->Run($param);
|
||||
$this->AddScript('structure.js');
|
||||
$admin = AuthDAL::GetAdmin();
|
||||
$this->user = $admin;
|
||||
|
||||
$this->smarty->assign('titleAdmin', 'Administracja');
|
||||
|
||||
$struct = array(
|
||||
//'User' => array('User' => 'Index'),
|
||||
'Słowniki' => array('Dictionary' => 'Index'),
|
||||
'Zmienne serwisu' => array('Setup' => 'Index'),
|
||||
//'Kategorie produktów' => array('ProductCategory' => 'Index'),
|
||||
'Parametry produktów' => array('ProductAttribute' => 'Index')
|
||||
|
||||
|
||||
);
|
||||
|
||||
$this->smarty->assign('structure',$this->renderStruct($struct));
|
||||
|
||||
}
|
||||
|
||||
private function renderStruct($struct){
|
||||
$return = '';
|
||||
|
||||
foreach($struct AS $k => $row){
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig',$row).'">'.$k.'</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function PostDispatch($param) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
572
Admin/controller/ProductCategoryController.php
Normal file
572
Admin/controller/ProductCategoryController.php
Normal file
@@ -0,0 +1,572 @@
|
||||
<?php
|
||||
/**
|
||||
* Produkty
|
||||
*
|
||||
*
|
||||
*/
|
||||
class ProductCategoryController extends MainController implements ControllerInterface {
|
||||
|
||||
|
||||
const AVATAR_DEST_DIR = '/upload/Product';
|
||||
const AVATAR_TEMP_DIR = '/upload/temp';
|
||||
const NO_PHOTO_IMG_BIG = "image/Admin/cropperNoPhotoBig.gif";
|
||||
const NO_PHOTO_IMG_SMALL = "image/Admin/przekatne.gif";
|
||||
const MAX_AVATAR_FILE_SIZE = 5; //Rozmiar w mb
|
||||
const CROPPER_BIG_PHOTO_MAX_WIDTH = 800;
|
||||
const CROPPER_BIG_PHOTO_MAX_HEIGHT = 800;
|
||||
const PHOTO_WIDTH = 800;
|
||||
const PHOTO_HEIGHT = 600;
|
||||
|
||||
const IMAGE_MINI_WIDTH = 240;
|
||||
const IMAGE_MINI_HEIGHT = 180;
|
||||
const IMAGE_NORMAL_WIDTH = 800;
|
||||
const IMAGE_NORMAL_HEIGHT = 600;
|
||||
|
||||
|
||||
public function IndexAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
$dalData = MfProductCategoryDAL::GetDalDataObj();
|
||||
$dalData->setJoin(array('MfProductCategoryDescription' => ' LEFT JOIN mf_product_category_description ON mf_product_category.id_mf_product_category=mf_product_category_description.id_mf_product_category '));
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$arrayObjProductCategory = MfProductCategoryDAL::GetResult($dalData);
|
||||
|
||||
$param['runSharedVariable'] = 'linkedAttribute';
|
||||
$this->RunModuleController( 'ProductCategoryController', 'LinkedAttribute', $param, true);
|
||||
//
|
||||
// $param['runSharedVariable'] = 'unlinkedAttribute';
|
||||
// $this->RunModuleController( 'ProductCategoryController', 'UnlinkedAttribute', $param, true);
|
||||
foreach ($arrayObjProductCategory as $item) {
|
||||
$menu[$item->GetId()] = $item;
|
||||
}
|
||||
foreach ($menu as $key => $obj) {
|
||||
|
||||
if ($obj->GetIdParent() != 0) {
|
||||
if (key_exists($obj->GetIdParent(), $menu)) {
|
||||
$menu[$obj->GetIdParent()]->SetHaveChildren(true);
|
||||
$menu[$obj->GetIdParent()]->AddChildren(array($obj->GetId() => $obj));
|
||||
} else {
|
||||
$arrayTree[$key] = $obj;
|
||||
}
|
||||
|
||||
}
|
||||
if ($obj->GetIdParent() == 0) {
|
||||
//Utils::ArrayDisplay('ones');
|
||||
$arrayTree[$key] = $obj;
|
||||
}
|
||||
}
|
||||
foreach ($menu as $key => $obj) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Utils::ArrayDisplay($arrayTree);
|
||||
|
||||
$this->smarty->assign('menuProductCategory', $arrayTree);
|
||||
$this->smarty->assign('arrayObjProductCategory', $arrayObjProductCategory);
|
||||
//Utils::ArrayDisplay($arrayObjProductCategory);
|
||||
}
|
||||
|
||||
public function LinkedAttributeAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
if (isset($param['idCategory'])) {
|
||||
$idsAttribute = MfProductLinkDAL::GetIdStringDestinaion('mf_product_category', 'mf_product_attribute', $param['idCategory'], 'pl');
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idsAttribute.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
$dalData->setSortBy(' FIELD(mf_product_attribute.id_mf_product_attribute, '.$idsAttribute.')');
|
||||
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('idCategory', $param['idCategory']);
|
||||
} else {
|
||||
$this->smarty->assign('arrayObjAttribute', array());
|
||||
$this->smarty->assign('clikCategory', true);
|
||||
}
|
||||
}
|
||||
|
||||
public function SaveSortAction($param) {
|
||||
$this->SetNoRender();
|
||||
//Utils::ArrayDisplay($param);
|
||||
if (Request::GetPost('doSaveSort')) {
|
||||
$arrayAttrSort = Request::GetPost('attr');
|
||||
$idCategory = Request::GetPost('idCategory');
|
||||
//Utils::ArrayDisplay($arrayAttrSort);
|
||||
//source_type id_source destination_type id_destination
|
||||
//mf_product_category 2 mf_product_attribute 6 0
|
||||
foreach ($_POST['attr'] as $idAttr => $sort) {
|
||||
//Utils::ArrayDisplay($idAttr);
|
||||
$dalData = MfProductLinkDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('source_type' => 'mf_product_category', 'id_source' => $idCategory, 'destination_type'=> 'mf_product_attribute', 'id_destination' => $idAttr, 'lang' => 'pl'));
|
||||
$arrayAttrLink = MfProductLinkDAL::GetResult($dalData);
|
||||
|
||||
//Utils::ArrayDisplay($arrayAttrLink);
|
||||
|
||||
foreach ($arrayAttrLink as $link) {
|
||||
$link->setWeight($sort);
|
||||
//Utils::ArrayDisplay($link);
|
||||
MfProductLinkDAL::Save($link);
|
||||
}
|
||||
}
|
||||
// Utils::ArrayDisplay($_POST);
|
||||
|
||||
}
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editCategory', array('ProductCategory' => 'index', 'idCategory' => $idCategory)));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function UnlinkedAttributeAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
if (isset($param['idCategory'])) {
|
||||
$idsAttribute = MfProductLinkDAL::GetIdStringDestinaion('mf_product_category', 'mf_product_attribute', $param['idCategory'], $param['lang']);
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => 'pl'));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute NOT IN ('.$idsAttribute.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
} else {
|
||||
$this->smarty->assign('arrayObjAttribute', array());
|
||||
$this->smarty->assign('clikCategory', true);
|
||||
}
|
||||
}
|
||||
|
||||
public function IndexStructureAction($param) {
|
||||
|
||||
$idCategory = SessionProxy::GetValue('idCategory');
|
||||
$this->smarty->assign('idCategory', $idCategory);
|
||||
|
||||
$idsProduct = MfProductLinkDAL::GetIdStringDestinaion('mf_product_category', 'mf_product',$idCategory, $param['lang']);
|
||||
|
||||
$dalData = MfProductDAL::GetDalDataObj();
|
||||
$dalData->setJoin(array('MfProductDescription' => ' LEFT JOIN mf_product_description ON mf_product.id_mf_product=mf_product_description.id_mf_product '));
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
//Utils::ArrayDisplay('ss'.$idsProduct);
|
||||
$dalData->addCondition(' ', 'mf_product.id_mf_product IN (' .$idsProduct. ') ', ' ');
|
||||
$arrayObj = MfProductDAL::GetResult($dalData);
|
||||
|
||||
$this->smarty->assign('arrayObj', $arrayObj);
|
||||
if (isset($param['methodToRun']) && $param['methodToRun'] == 'Add') {
|
||||
$this->smarty->assign('add', true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function AddAction($param) {
|
||||
|
||||
|
||||
|
||||
// Pobiernie rodziców kategorii
|
||||
$dalData = MfProductCategoryDAL::GetDalDataObj();
|
||||
$dalData->setJoin(array('MfProductCategoryDescription' => ' LEFT JOIN mf_product_category_description ON mf_product_category.id_mf_product_category=mf_product_category_description.id_mf_product_category '));
|
||||
$dalData->setCondition(array('lang' => $param['lang'], 'mf_product_category.id_parent' => 0));
|
||||
$arrayObjProductCategory = MfProductCategoryDAL::GetResult($dalData);
|
||||
|
||||
//$param['runSharedVariable'] = 'linkedAttribute';
|
||||
//$this->RunModuleController( 'ProductCategoryController', 'LinkedAttribute', $param, true);
|
||||
//
|
||||
// $param['runSharedVariable'] = 'unlinkedAttribute';
|
||||
// $this->RunModuleController( 'ProductCategoryController', 'UnlinkedAttribute', $param, true);
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjProductCategory);
|
||||
$this->smarty->assign('arrayObjProductCategory', $arrayObjProductCategory);
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
// $dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idsAttribute.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
//$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_category', $idCategory, 'mf_product_attribute');
|
||||
//Utils::ArrayDisplay($arrayObjAttribue);
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('arrayObjAttributeLinked', array());
|
||||
$objCategoryProduct = MfProductCategoryDAL::GetEmptyObj();
|
||||
|
||||
if (Request::GetPost('doCategoryAdd')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
//$objProduct = new MfProduct();
|
||||
//$objCategoryProduct->setDate($data['datepublication']." ".$data['timepublication'].":00:00");
|
||||
|
||||
$objCategoryProduct->setPublication($publication);
|
||||
$objCategoryProduct->setIdParent($data['idParent']);
|
||||
$objCategoryProduct->setWeight($data['weight']);
|
||||
$objCategoryProductDesc = new MfProductCategoryDescription();
|
||||
$objCategoryProductDesc->setDatePublication("0000-00-00 00:00:00");
|
||||
$objCategoryProductDesc->setLang('pl');
|
||||
$objCategoryProductDesc->setName($data['name']);
|
||||
$objCategoryProductDesc->setPublication($publication);
|
||||
|
||||
//$arrayObjAttributeWithValue = array();
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjAttribute);
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
|
||||
$idCategoryProduct = MfProductCategoryDAL::Save($objCategoryProduct);
|
||||
$objCategoryProductDesc->setIdMfProductCategory($idCategoryProduct);
|
||||
$objCategoryProductDescEn = $objCategoryProductDesc;
|
||||
//$objCategoryProductDescEn->setLang('en');
|
||||
$objCategoryProductDescRu = $objCategoryProductDesc;
|
||||
//$objCategoryProductDescRu->setLang('ru');
|
||||
|
||||
|
||||
MfProductCategoryDescriptionDAL::Save($objCategoryProductDesc);
|
||||
///Utils::ArrayDisplay($objCategoryProductDesc);
|
||||
$objCategoryProductDescEn->setLang('en');
|
||||
$objCategoryProductDescEn->setId(-1);
|
||||
MfProductCategoryDescriptionDAL::Save($objCategoryProductDescEn);
|
||||
//Utils::ArrayDisplay($objCategoryProductDesc);
|
||||
$objCategoryProductDescRu->setLang('ru');
|
||||
$objCategoryProductDescRu->setId(-1);
|
||||
MfProductCategoryDescriptionDAL::Save($objCategoryProductDescRu);
|
||||
//Utils::ArrayDisplay($objCategoryProductDesc);
|
||||
if (isset($data['attr'])) {
|
||||
|
||||
foreach ($data['attr'] as $attrKey => $attrId ) {
|
||||
$objMfProductLink = new MfProductLink();
|
||||
$objMfProductLink->setDestinationType('mf_product_attribute');
|
||||
$objMfProductLink->setSourceType('mf_product_category');
|
||||
$objMfProductLink->setIdDestination($attrId);
|
||||
$objMfProductLink->setIdSource($idCategoryProduct);
|
||||
$objMfProductLink->setLang('pl');
|
||||
$objMfProductLink->setPublication(1);
|
||||
MfProductLinkDAL::Save($objMfProductLink);
|
||||
}
|
||||
|
||||
}
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editCategory', array('ProductCategory' => 'index')));
|
||||
} else {
|
||||
|
||||
if (isset($data['attr'])) {
|
||||
$idAttrLinked = implode(', ',$data['attr']);
|
||||
} else {
|
||||
$idAttrLinked = '-1';
|
||||
}
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idAttrLinked.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttributeLinked = MfProductAttributeDAL::GetResult($dalData);
|
||||
//$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_category', $idCategory, 'mf_product_attribute');
|
||||
//Utils::ArrayDisplay($arrayObjAttributeLinked);
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute NOT IN ('.$idAttrLinked.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('arrayObjAttributeLinked', $arrayObjAttributeLinked);
|
||||
|
||||
|
||||
$objCategoryProduct->SetDescriptionObj($objCategoryProductDesc);
|
||||
$this->smarty->assign('objCategoryProduct',$objCategoryProduct);
|
||||
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
|
||||
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function EditAction($param) {
|
||||
|
||||
|
||||
// Pobiernie rodziców kategorii
|
||||
$dalData = MfProductCategoryDAL::GetDalDataObj();
|
||||
$dalData->setJoin(array('MfProductCategoryDescription' => ' LEFT JOIN mf_product_category_description ON mf_product_category.id_mf_product_category=mf_product_category_description.id_mf_product_category '));
|
||||
$dalData->setCondition(array('lang' => $param['lang'], 'mf_product_category.id_parent' => 0, ' ' => array('value' => ' mf_product_category.id_mf_product_category NOT IN('.$param['id'].')' ,'condition' => '')));
|
||||
$arrayObjProductCategory = MfProductCategoryDAL::GetResult($dalData);
|
||||
|
||||
//$param['runSharedVariable'] = 'linkedAttribute';
|
||||
//$this->RunModuleController( 'ProductCategoryController', 'LinkedAttribute', $param, true);
|
||||
//
|
||||
// $param['runSharedVariable'] = 'unlinkedAttribute';
|
||||
// $this->RunModuleController( 'ProductCategoryController', 'UnlinkedAttribute', $param, true);
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjProductCategory);
|
||||
$this->smarty->assign('arrayObjProductCategory', $arrayObjProductCategory);
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
$idsAttribute = MfProductLinkDAL::GetIdStringDestinaion('mf_product_category', 'mf_product_attribute', $param['id'], 'pl');
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute NOT IN ('.$idsAttribute.') ', ' ');
|
||||
$dalData->setSortBy(' FIELD(mf_product_attribute.id_mf_product_attribute, '.$idsAttribute.')');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idsAttribute.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
$dalData->setSortBy(' FIELD(mf_product_attribute.id_mf_product_attribute, '.$idsAttribute.')');
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttributeLinked = MfProductAttributeDAL::GetResult($dalData);
|
||||
//$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_category', $idCategory, 'mf_product_attribute');
|
||||
//Utils::ArrayDisplay($arrayObjAttribue);
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('arrayObjAttributeLinked', $arrayObjAttributeLinked);
|
||||
$objCategoryProduct = MfProductCategoryDAL::GetById($param['id'], $param['lang']);
|
||||
$this->smarty->assign('objCategoryProduct', $objCategoryProduct);
|
||||
|
||||
if (Request::GetPost('doCategoryEdit')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
//$objProduct = new MfProduct();
|
||||
//$objCategoryProduct->setDate($data['datepublication']." ".$data['timepublication'].":00:00");
|
||||
$objCategoryProduct->setDatePublication("0000-00-00 00:00:00");
|
||||
$objCategoryProduct->setPublication($publication);
|
||||
$objCategoryProduct->setIdParent($data['idParent']);
|
||||
|
||||
$objCategoryProduct->setWeight($data['weight']);
|
||||
$objCategoryProductDesc = $objCategoryProduct->getDescriptionObj();
|
||||
$objCategoryProductDesc->setDatePublication("0000-00-00 00:00:00");
|
||||
$objCategoryProductDesc->setLang($param['lang']);
|
||||
$objCategoryProductDesc->setName($data['name']);
|
||||
$objCategoryProductDesc->setPublication($publication);
|
||||
|
||||
//$arrayObjAttributeWithValue = array();
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjAttribute);
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
//Utils::ArrayDisplay($data);
|
||||
$idCategoryProduct = MfProductCategoryDAL::Save($objCategoryProduct);
|
||||
$objCategoryProductDesc->setIdMfProductCategory($idCategoryProduct);
|
||||
MfProductCategoryDescriptionDAL::Save($objCategoryProductDesc);
|
||||
|
||||
|
||||
MfProductLinkDAL::DeleteFromLink($idCategoryProduct, 'mf_product_category', null, 'mf_product_attribute');
|
||||
|
||||
foreach ($data['attr'] as $attrKey => $attrId ) {
|
||||
$objMfProductLink = new MfProductLink();
|
||||
$objMfProductLink->setDestinationType('mf_product_attribute');
|
||||
$objMfProductLink->setSourceType('mf_product_category');
|
||||
$objMfProductLink->setIdDestination($attrId);
|
||||
$objMfProductLink->setIdSource($idCategoryProduct);
|
||||
$objMfProductLink->setLang('pl');
|
||||
$objMfProductLink->setPublication(1);
|
||||
$objMfProductLink->setWeight($data['linked_attr_weight'][$attrId]);
|
||||
//Utils::ArrayDisplay($objMfProductLink);
|
||||
MfProductLinkDAL::Save($objMfProductLink);
|
||||
}
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editCategory', array('ProductCategory' => 'index')));
|
||||
} else {
|
||||
|
||||
if (isset($data['attr'])) {
|
||||
$idAttrLinked = implode(', ',$data['attr']);
|
||||
} else {
|
||||
$idAttrLinked = '-1';
|
||||
}
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idAttrLinked.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttributeLinked = MfProductAttributeDAL::GetResult($dalData);
|
||||
//$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_category', $idCategory, 'mf_product_attribute');
|
||||
//Utils::ArrayDisplay($arrayObjAttributeLinked);
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute NOT IN ('.$idAttrLinked.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('arrayObjAttributeLinked', $arrayObjAttributeLinked);
|
||||
|
||||
|
||||
$objCategoryProduct->SetDescriptionObj($objCategoryProductDesc);
|
||||
$this->smarty->assign('objCategoryProduct',$objCategoryProduct);
|
||||
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
|
||||
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function AjaxAddLinkAttrAction($param) {
|
||||
//$array
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function DeleteAction($param) {
|
||||
$isLinked = MfProductLinkDAL::IsLinked($param['id'], 'mf_product_category', null, 'mf_product');
|
||||
$delete = true;
|
||||
$error = '';
|
||||
if ($isLinked > 0 ) {
|
||||
$delete = false;
|
||||
}
|
||||
|
||||
$arrayLang = (Router::$arrayLang);
|
||||
unset($arrayLang[$param['lang']]);
|
||||
$langString = implode(',', $arrayLang);
|
||||
|
||||
$isLang = MfProductCategoryDAL::CheakDescLang($param['id'], $param['lang']);
|
||||
|
||||
// if ($isLang) {
|
||||
// $delete = false;
|
||||
// }
|
||||
|
||||
if ($delete) {
|
||||
|
||||
foreach (Router::$arrayLang as $lang) {
|
||||
$objCategory = MfProductCategoryDAL::GetById($param['id'], $lang);
|
||||
$objCategoryDesc = $objCategory->getDescriptionObj();
|
||||
$dalDataDesc = MfProductCategoryDescriptionDAL::GetDalDataObj();
|
||||
$dalDataDesc->setObj($objCategoryDesc);
|
||||
MfProductCategoryDescriptionDAL::Delete($dalDataDesc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$dalData = MfProductCategoryDAL::GetDalDataObj();
|
||||
$dalData->setObj($objCategory);
|
||||
MfProductCategoryDAL::Delete($dalData);
|
||||
$this->AddRedirectInfo('Element został usunięty', 'ok', Router::GenerateUrl('editCategory', array('ProductCategory' => 'Index')));
|
||||
} else {
|
||||
if ($isLinked) {
|
||||
$error .= 'Kategoria jest powiązana z produktem.';
|
||||
}
|
||||
// if ($isLang) {
|
||||
// $error .= $error ? '<br/><br/>' : '';
|
||||
// $error .= 'Kategoria posiada wersję jezykową';
|
||||
// }
|
||||
$this->AddRedirectInfo($error, 'error', Router::GenerateUrl('editCategory', array('ProductCategory' => 'Index')));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wspolna metoda
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
|
||||
|
||||
$this->RunShared('Auth', $param);
|
||||
$this->Run($param);
|
||||
$this->AddScript('structure.js');
|
||||
$admin = AuthDAL::GetAdmin();
|
||||
$this->user = $admin;
|
||||
|
||||
$this->smarty->assign('titleAdmin', 'Administracja');
|
||||
|
||||
$struct = array(
|
||||
//'User' => array('User' => 'Index'),
|
||||
'Słowniki' => array('Dictionary' => 'Index'),
|
||||
'Zmienne serwisu' => array('Setup' => 'Index'),
|
||||
'Kategorie produktów' => array('ProductCategory' => 'Index'),
|
||||
'Serie produktów' => array('ProductSeries' => 'Index'),
|
||||
'Materiał produktów' => array('ProductSpec' => 'Index', 'type' => 2),
|
||||
'Kolor produktów' => array('ProductSpec' => 'Index', 'type' => 1),
|
||||
'Żarówki produktów' => array('ProductSpec' => 'Index', 'type' => 3),
|
||||
//'Parametry produktów' => array('ProductAttribute' => 'Index')
|
||||
|
||||
|
||||
);
|
||||
|
||||
$this->smarty->assign('structure',$this->renderStruct($struct));
|
||||
|
||||
}
|
||||
|
||||
private function renderStruct($struct){
|
||||
$return = '';
|
||||
|
||||
foreach($struct AS $k => $row){
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig',$row).'">'.$k.'</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function PostDispatch($param) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
2026
Admin/controller/ProductController.php
Normal file
2026
Admin/controller/ProductController.php
Normal file
File diff suppressed because it is too large
Load Diff
308
Admin/controller/ProductSeriesController.php
Normal file
308
Admin/controller/ProductSeriesController.php
Normal file
@@ -0,0 +1,308 @@
|
||||
<?php
|
||||
/**
|
||||
* Produkty serie
|
||||
*
|
||||
*
|
||||
*/
|
||||
class ProductSeriesController extends MainController implements ControllerInterface {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function IndexAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
$dalData = ShopSeriesDAL::GetDalDataObj();
|
||||
//$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$arryObjSeries = ShopSeriesDAL::GetResult($dalData);
|
||||
|
||||
$this->smarty->assign('arrayObj', $arryObjSeries);
|
||||
}
|
||||
|
||||
|
||||
public function AddAction($param) {
|
||||
|
||||
|
||||
|
||||
// Pobiernie rodziców kategorii
|
||||
$dalData = MfProductCategoryDAL::GetDalDataObj();
|
||||
$dalData->setJoin(array('MfProductCategoryDescription' => ' LEFT JOIN mf_product_category_description ON mf_product_category.id_mf_product_category=mf_product_category_description.id_mf_product_category '));
|
||||
$dalData->setCondition(array('lang' => $param['lang'], 'mf_product_category.id_parent' => 0));
|
||||
$arrayObjProductCategory = MfProductCategoryDAL::GetResult($dalData);
|
||||
|
||||
//$param['runSharedVariable'] = 'linkedAttribute';
|
||||
//$this->RunModuleController( 'ProductCategoryController', 'LinkedAttribute', $param, true);
|
||||
//
|
||||
// $param['runSharedVariable'] = 'unlinkedAttribute';
|
||||
// $this->RunModuleController( 'ProductCategoryController', 'UnlinkedAttribute', $param, true);
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjProductCategory);
|
||||
$this->smarty->assign('arrayObjProductCategory', $arrayObjProductCategory);
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
// $dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idsAttribute.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
//$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_category', $idCategory, 'mf_product_attribute');
|
||||
//Utils::ArrayDisplay($arrayObjAttribue);
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('arrayObjAttributeLinked', array());
|
||||
$objCategoryProduct = MfProductCategoryDAL::GetEmptyObj();
|
||||
|
||||
if (Request::GetPost('doCategoryAdd')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
//$objProduct = new MfProduct();
|
||||
//$objCategoryProduct->setDate($data['datepublication']." ".$data['timepublication'].":00:00");
|
||||
|
||||
$objCategoryProduct->setPublication($publication);
|
||||
$objCategoryProduct->setIdParent($data['idParent']);
|
||||
$objCategoryProduct->setWeight($data['weight']);
|
||||
$objCategoryProductDesc = new MfProductCategoryDescription();
|
||||
$objCategoryProductDesc->setDatePublication("0000-00-00 00:00:00");
|
||||
$objCategoryProductDesc->setLang('pl');
|
||||
$objCategoryProductDesc->setName($data['name']);
|
||||
$objCategoryProductDesc->setPublication($publication);
|
||||
|
||||
//$arrayObjAttributeWithValue = array();
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjAttribute);
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
|
||||
$idCategoryProduct = MfProductCategoryDAL::Save($objCategoryProduct);
|
||||
$objCategoryProductDesc->setIdMfProductCategory($idCategoryProduct);
|
||||
$objCategoryProductDescEn = $objCategoryProductDesc;
|
||||
//$objCategoryProductDescEn->setLang('en');
|
||||
$objCategoryProductDescRu = $objCategoryProductDesc;
|
||||
//$objCategoryProductDescRu->setLang('ru');
|
||||
|
||||
|
||||
MfProductCategoryDescriptionDAL::Save($objCategoryProductDesc);
|
||||
///Utils::ArrayDisplay($objCategoryProductDesc);
|
||||
$objCategoryProductDescEn->setLang('en');
|
||||
$objCategoryProductDescEn->setId(-1);
|
||||
MfProductCategoryDescriptionDAL::Save($objCategoryProductDescEn);
|
||||
//Utils::ArrayDisplay($objCategoryProductDesc);
|
||||
$objCategoryProductDescRu->setLang('ru');
|
||||
$objCategoryProductDescRu->setId(-1);
|
||||
MfProductCategoryDescriptionDAL::Save($objCategoryProductDescRu);
|
||||
//Utils::ArrayDisplay($objCategoryProductDesc);
|
||||
if (isset($data['attr'])) {
|
||||
|
||||
foreach ($data['attr'] as $attrKey => $attrId ) {
|
||||
$objMfProductLink = new MfProductLink();
|
||||
$objMfProductLink->setDestinationType('mf_product_attribute');
|
||||
$objMfProductLink->setSourceType('mf_product_category');
|
||||
$objMfProductLink->setIdDestination($attrId);
|
||||
$objMfProductLink->setIdSource($idCategoryProduct);
|
||||
$objMfProductLink->setLang('pl');
|
||||
$objMfProductLink->setPublication(1);
|
||||
MfProductLinkDAL::Save($objMfProductLink);
|
||||
}
|
||||
|
||||
}
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editCategory', array('ProductCategory' => 'index')));
|
||||
} else {
|
||||
|
||||
if (isset($data['attr'])) {
|
||||
$idAttrLinked = implode(', ',$data['attr']);
|
||||
} else {
|
||||
$idAttrLinked = '-1';
|
||||
}
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idAttrLinked.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttributeLinked = MfProductAttributeDAL::GetResult($dalData);
|
||||
//$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_category', $idCategory, 'mf_product_attribute');
|
||||
//Utils::ArrayDisplay($arrayObjAttributeLinked);
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute NOT IN ('.$idAttrLinked.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('arrayObjAttributeLinked', $arrayObjAttributeLinked);
|
||||
|
||||
|
||||
$objCategoryProduct->SetDescriptionObj($objCategoryProductDesc);
|
||||
$this->smarty->assign('objCategoryProduct',$objCategoryProduct);
|
||||
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
|
||||
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function EditAction($param) {
|
||||
|
||||
|
||||
|
||||
$objSeries = ShopSeriesDAL::GetById($param['id'], $param['lang']);
|
||||
$this->smarty->assign('obj', $objSeries);
|
||||
|
||||
if (Request::GetPost('doSeriesEdit')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
|
||||
$objSeries->setLang($param['lang']);
|
||||
$objSeries->setName($data['name']);
|
||||
$objSeries->setPublication($publication);
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
//Utils::ArrayDisplay($data);
|
||||
$idseries = ShopSeriesDAL::Save($objSeries);
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editSeries', array('ProductSeries' => 'index')));
|
||||
} else {
|
||||
|
||||
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function AjaxAddLinkAttrAction($param) {
|
||||
//$array
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function DeleteAction($param) {
|
||||
$isLinked = MfProductLinkDAL::IsLinked($param['id'], 'mf_product_series', null, 'mf_product');
|
||||
$delete = true;
|
||||
$error = '';
|
||||
if ($isLinked > 0 ) {
|
||||
$delete = false;
|
||||
}
|
||||
|
||||
if ($delete) {
|
||||
|
||||
$objSeries = ShopSeriesDAL::GetById($param['id']);
|
||||
$dalData = ShopSeriesDAL::GetDalDataObj();
|
||||
$dalData->setObj($objSeries);
|
||||
ShopSeriesDAL::Delete($dalData);
|
||||
$this->AddRedirectInfo('Element został usunięty', 'ok', Router::GenerateUrl('editSeries', array('ProductSeries' => 'Index')));
|
||||
} else {
|
||||
if ($isLinked) {
|
||||
$error .= 'seria jest powiązana z produktem.';
|
||||
}
|
||||
|
||||
$this->AddRedirectInfo($error, 'error', Router::GenerateUrl('editCategory', array('ProductSeries' => 'Index')));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wspolna metoda
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
|
||||
|
||||
$this->RunShared('Auth', $param);
|
||||
$this->Run($param);
|
||||
$this->AddScript('structure.js');
|
||||
$admin = AuthDAL::GetAdmin();
|
||||
$this->user = $admin;
|
||||
|
||||
$this->smarty->assign('titleAdmin', 'Administracja');
|
||||
|
||||
$struct = array(
|
||||
//'User' => array('User' => 'Index'),
|
||||
'Słowniki' => array('Dictionary' => 'Index'),
|
||||
'Zmienne serwisu' => array('Setup' => 'Index'),
|
||||
'Kategorie produktów' => array('ProductCategory' => 'Index'),
|
||||
'Serie produktów' => array('ProductSeries' => 'Index'),
|
||||
'Materiał produktów' => array('ProductSpec' => 'Index', 'type' => 2),
|
||||
'Kolor produktów' => array('ProductSpec' => 'Index', 'type' => 1),
|
||||
'Żarówki produktów' => array('ProductSpec' => 'Index', 'type' => 3),
|
||||
//'Parametry produktów' => array('ProductAttribute' => 'Index')
|
||||
|
||||
|
||||
);
|
||||
|
||||
$this->smarty->assign('structure',$this->renderStruct($struct));
|
||||
|
||||
}
|
||||
|
||||
private function renderStruct($struct){
|
||||
$return = '';
|
||||
|
||||
foreach($struct AS $k => $row){
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig',$row).'">'.$k.'</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function PostDispatch($param) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
340
Admin/controller/ProductSpecController.php
Normal file
340
Admin/controller/ProductSpecController.php
Normal file
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
/**
|
||||
* Produkty
|
||||
*
|
||||
*
|
||||
*/
|
||||
class ProductSpecController extends MainController implements ControllerInterface {
|
||||
|
||||
|
||||
const AVATAR_DEST_DIR = '/upload/Product';
|
||||
const AVATAR_TEMP_DIR = '/upload/temp';
|
||||
const NO_PHOTO_IMG_BIG = "image/Admin/cropperNoPhotoBig.gif";
|
||||
const NO_PHOTO_IMG_SMALL = "image/Admin/przekatne.gif";
|
||||
const MAX_AVATAR_FILE_SIZE = 5; //Rozmiar w mb
|
||||
const CROPPER_BIG_PHOTO_MAX_WIDTH = 800;
|
||||
const CROPPER_BIG_PHOTO_MAX_HEIGHT = 800;
|
||||
const PHOTO_WIDTH = 800;
|
||||
const PHOTO_HEIGHT = 600;
|
||||
|
||||
const IMAGE_MINI_WIDTH = 240;
|
||||
const IMAGE_MINI_HEIGHT = 180;
|
||||
const IMAGE_NORMAL_WIDTH = 800;
|
||||
const IMAGE_NORMAL_HEIGHT = 600;
|
||||
|
||||
|
||||
public function IndexAction($param) {
|
||||
//Utils::ArrayDisplay($param);
|
||||
$dalData = MfProductSpecificationDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->setCondition(array('typ' => isset($param['type']) ? $param['type'] : 1));
|
||||
|
||||
$arrayObjProductSpec = MfProductSpecificationDAL::GetResult($dalData);
|
||||
|
||||
|
||||
|
||||
$this->smarty->assign('arrayObj', $arrayObjProductSpec);
|
||||
//Utils::ArrayDisplay($arrayObjProductSpec);
|
||||
}
|
||||
|
||||
public function AddAction($param) {
|
||||
|
||||
|
||||
|
||||
// Pobiernie rodziców kategorii
|
||||
$dalData = MfProductSpecDAL::GetDalDataObj();
|
||||
$dalData->setJoin(array('MfProductSpecDescription' => ' LEFT JOIN mf_product_category_description ON mf_product_category.id_mf_product_category=mf_product_category_description.id_mf_product_category '));
|
||||
$dalData->setCondition(array('lang' => $param['lang'], 'mf_product_category.id_parent' => 0));
|
||||
$arrayObjProductSpec = MfProductSpecDAL::GetResult($dalData);
|
||||
|
||||
//$param['runSharedVariable'] = 'linkedAttribute';
|
||||
//$this->RunModuleController( 'ProductSpecController', 'LinkedAttribute', $param, true);
|
||||
//
|
||||
// $param['runSharedVariable'] = 'unlinkedAttribute';
|
||||
// $this->RunModuleController( 'ProductSpecController', 'UnlinkedAttribute', $param, true);
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjProductSpec);
|
||||
$this->smarty->assign('arrayObjProductSpec', $arrayObjProductSpec);
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
// $dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idsAttribute.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
//$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_category', $idCategory, 'mf_product_attribute');
|
||||
//Utils::ArrayDisplay($arrayObjAttribue);
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('arrayObjAttributeLinked', array());
|
||||
$objCategoryProduct = MfProductSpecDAL::GetEmptyObj();
|
||||
|
||||
if (Request::GetPost('doCategoryAdd')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
//$objProduct = new MfProduct();
|
||||
//$objCategoryProduct->setDate($data['datepublication']." ".$data['timepublication'].":00:00");
|
||||
|
||||
$objCategoryProduct->setPublication($publication);
|
||||
$objCategoryProduct->setIdParent($data['idParent']);
|
||||
$objCategoryProduct->setWeight($data['weight']);
|
||||
$objCategoryProductDesc = new MfProductSpecDescription();
|
||||
$objCategoryProductDesc->setDatePublication("0000-00-00 00:00:00");
|
||||
$objCategoryProductDesc->setLang('pl');
|
||||
$objCategoryProductDesc->setName($data['name']);
|
||||
$objCategoryProductDesc->setPublication($publication);
|
||||
|
||||
//$arrayObjAttributeWithValue = array();
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjAttribute);
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
|
||||
$idCategoryProduct = MfProductSpecDAL::Save($objCategoryProduct);
|
||||
$objCategoryProductDesc->setIdMfProductSpec($idCategoryProduct);
|
||||
$objCategoryProductDescEn = $objCategoryProductDesc;
|
||||
//$objCategoryProductDescEn->setLang('en');
|
||||
$objCategoryProductDescRu = $objCategoryProductDesc;
|
||||
//$objCategoryProductDescRu->setLang('ru');
|
||||
|
||||
|
||||
MfProductSpecDescriptionDAL::Save($objCategoryProductDesc);
|
||||
///Utils::ArrayDisplay($objCategoryProductDesc);
|
||||
$objCategoryProductDescEn->setLang('en');
|
||||
$objCategoryProductDescEn->setId(-1);
|
||||
MfProductSpecDescriptionDAL::Save($objCategoryProductDescEn);
|
||||
//Utils::ArrayDisplay($objCategoryProductDesc);
|
||||
$objCategoryProductDescRu->setLang('ru');
|
||||
$objCategoryProductDescRu->setId(-1);
|
||||
MfProductSpecDescriptionDAL::Save($objCategoryProductDescRu);
|
||||
//Utils::ArrayDisplay($objCategoryProductDesc);
|
||||
if (isset($data['attr'])) {
|
||||
|
||||
foreach ($data['attr'] as $attrKey => $attrId ) {
|
||||
$objMfProductLink = new MfProductLink();
|
||||
$objMfProductLink->setDestinationType('mf_product_attribute');
|
||||
$objMfProductLink->setSourceType('mf_product_category');
|
||||
$objMfProductLink->setIdDestination($attrId);
|
||||
$objMfProductLink->setIdSource($idCategoryProduct);
|
||||
$objMfProductLink->setLang('pl');
|
||||
$objMfProductLink->setPublication(1);
|
||||
MfProductLinkDAL::Save($objMfProductLink);
|
||||
}
|
||||
|
||||
}
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editCategory', array('ProductSpec' => 'index')));
|
||||
} else {
|
||||
|
||||
if (isset($data['attr'])) {
|
||||
$idAttrLinked = implode(', ',$data['attr']);
|
||||
} else {
|
||||
$idAttrLinked = '-1';
|
||||
}
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute IN ('.$idAttrLinked.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttributeLinked = MfProductAttributeDAL::GetResult($dalData);
|
||||
//$objProductAttribute = MfProductAttributeDAL::GetResultByLink('mf_product_category', $idCategory, 'mf_product_attribute');
|
||||
//Utils::ArrayDisplay($arrayObjAttributeLinked);
|
||||
|
||||
$dalData = MfProductAttributeDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array('lang' => $param['lang']));
|
||||
$dalData->addCondition(' ', 'mf_product_attribute.id_mf_product_attribute NOT IN ('.$idAttrLinked.') ', ' ');
|
||||
$dalData->setJoin(array('MfProductAttributeDescription' => ' LEFT JOIN mf_product_attribute_description ON mf_product_attribute.id_mf_product_attribute=mf_product_attribute_description.id_mf_product_attribute '));
|
||||
|
||||
//Utils::ArrayDisplay($dalData);
|
||||
$arrayObjAttribute = MfProductAttributeDAL::GetResult($dalData);
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('arrayObjAttributeLinked', $arrayObjAttributeLinked);
|
||||
|
||||
|
||||
$objCategoryProduct->SetDescriptionObj($objCategoryProductDesc);
|
||||
$this->smarty->assign('objCategoryProduct',$objCategoryProduct);
|
||||
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
|
||||
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function EditAction($param) {
|
||||
|
||||
|
||||
// Pobiernie rodziców kategorii
|
||||
$dalData = MfProductSpecificationDAL::GetDalDataObj();
|
||||
|
||||
$objSpec = MfProductSpecificationDAL::GetById($param['id'], $param['lang']);
|
||||
$this->smarty->assign('obj', $objSpec);
|
||||
|
||||
if (Request::GetPost('doSpecEdit')) {
|
||||
//Utils::ArrayDisplay(Request::GetAllPost());
|
||||
|
||||
$out = array();
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
$data = Request::GetAllPost();
|
||||
|
||||
$validator->IsEmpty('name', 'Pole nazwa musi zostać wypełnione.');
|
||||
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
$publication = Request::Get('publication');
|
||||
$publication ? $publication = 1 : $publication = '0';
|
||||
|
||||
//$objProduct = new MfProduct();
|
||||
//$objCategoryProduct->setDate($data['datepublication']." ".$data['timepublication'].":00:00");
|
||||
$objSpec->setPublication($publication);
|
||||
//$objSpec->setWeight($data['weight']);
|
||||
$objSpec->setLang($param['lang']);
|
||||
$objSpec->setValue($data['name']);
|
||||
|
||||
//$arrayObjAttributeWithValue = array();
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjAttribute);
|
||||
|
||||
if(empty($out)) {
|
||||
|
||||
//Utils::ArrayDisplay($data);
|
||||
$idSpec = MfProductSpecificationDAL::Save($objSpec);
|
||||
|
||||
|
||||
|
||||
$this->AddRedirectInfo('Zapisano', 'ok', Router::GenerateUrl('editSpec', array('ProductSpec' => 'Index', 'type' => $objSpec->GetTyp())));
|
||||
} else {
|
||||
|
||||
$this->smarty->assign('arrayObjAttribute', $arrayObjAttribute);
|
||||
$this->smarty->assign('info','Pola obowiązkowe muszą zostać wypełnione.');
|
||||
$this->smarty->assign('type','error');
|
||||
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
|
||||
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function AjaxAddLinkAttrAction($param) {
|
||||
//$array
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function DeleteAction($param) {
|
||||
$isLinked = MfProductLinkDAL::IsLinked($param['id'], 'mf_product_specyfication', null, 'mf_product');
|
||||
$delete = true;
|
||||
$error = '';
|
||||
if ($isLinked > 0 ) {
|
||||
$delete = false;
|
||||
}
|
||||
$objSpec = MfProductSpecificationDAL::GetById($param['id']);
|
||||
if ($delete) {
|
||||
|
||||
|
||||
$dalData = MfProductSpecificationDAL::GetDalDataObj();
|
||||
$dalData->setObj($objSpec);
|
||||
MfProductSpecificationDAL::Delete($dalData);
|
||||
$this->AddRedirectInfo('Element został usunięty', 'ok', Router::GenerateUrl('editSpec', array('ProductSpec' => 'Index', 'type' => $objSpec->GetTyp())));
|
||||
} else {
|
||||
if ($isLinked) {
|
||||
$error .= 'Parametr jest powiązana z produktem.';
|
||||
}
|
||||
|
||||
$this->AddRedirectInfo($error, 'error', Router::GenerateUrl('editSpec', array('ProductSpec' => 'Index', 'type' => $objSpec->GetTyp())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wspolna metoda
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
|
||||
|
||||
$this->RunShared('Auth', $param);
|
||||
$this->Run($param);
|
||||
$this->AddScript('structure.js');
|
||||
$admin = AuthDAL::GetAdmin();
|
||||
$this->user = $admin;
|
||||
|
||||
$this->smarty->assign('titleAdmin', 'Administracja');
|
||||
|
||||
$struct = array(
|
||||
//'User' => array('User' => 'Index'),
|
||||
'Słowniki' => array('Dictionary' => 'Index'),
|
||||
'Zmienne serwisu' => array('Setup' => 'Index'),
|
||||
'Kategorie produktów' => array('ProductCategory' => 'Index'),
|
||||
'Serie produktów' => array('ProductSeries' => 'Index'),
|
||||
'Materiał produktów' => array('ProductSpec' => 'Index', 'type' => 2),
|
||||
'Kolor produktów' => array('ProductSpec' => 'Index', 'type' => 1),
|
||||
'Żarówki produktów' => array('ProductSpec' => 'Index', 'type' => 3),
|
||||
//'Parametry produktów' => array('ProductAttribute' => 'Index')
|
||||
|
||||
|
||||
);
|
||||
|
||||
$this->smarty->assign('structure',$this->renderStruct($struct));
|
||||
|
||||
}
|
||||
|
||||
private function renderStruct($struct){
|
||||
$return = '';
|
||||
|
||||
foreach($struct AS $k => $row){
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig',$row).'">'.$k.'</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function PostDispatch($param) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
171
Admin/controller/SetupController.php
Normal file
171
Admin/controller/SetupController.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* $Id: SetupController.php 639 2008-06-18 10:51:32Z mija $
|
||||
* Kontroler Ustawien
|
||||
*
|
||||
*/
|
||||
class SetupController extends MainController implements ControllerInterface {
|
||||
/**
|
||||
* Strona glowna
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
if ( isset($_REQUEST["addVariable"]) ) {
|
||||
//Utils::ArrayDisplay($_REQUEST);
|
||||
SetupDAL::SaveVariable($_REQUEST["variable"], $_REQUEST["value"], $_REQUEST["description"]);
|
||||
}
|
||||
$this->smarty->assign('arrayVariables', SetupDAL::GetAllVariables(false) );
|
||||
|
||||
|
||||
//Utils::ArrayDisplay(SetupDAL::GetAllVariables(false));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nowy parametr
|
||||
*
|
||||
*/
|
||||
public function NewAction() {
|
||||
$this->partialTemplate = 'Edit.tpl';
|
||||
$this->smarty->assign('objVariable', NULL );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Edycja parametru
|
||||
*
|
||||
* @param array $param
|
||||
*/
|
||||
public function EditAction($param) {
|
||||
//$this->partialTemplate = 'Edit.tpl';
|
||||
|
||||
|
||||
$objVariable = SetupDAL::GetVariableByName($param["variable"]);
|
||||
|
||||
$this->smarty->assign('objVariable', $objVariable );
|
||||
}
|
||||
|
||||
/**
|
||||
* Czyszczenie cache strony
|
||||
*
|
||||
*/
|
||||
public function ClearCacheAction() {
|
||||
|
||||
|
||||
$directory = PATH_SITE_CACHE;
|
||||
|
||||
if( !$dirhandle = @opendir($directory) )
|
||||
return;
|
||||
|
||||
while( false !== ($filename = readdir($dirhandle)) ) {
|
||||
if( $filename != "." && $filename != ".." ) {
|
||||
$filename = $directory. "/". $filename;
|
||||
if(is_file($filename)) {
|
||||
@unlink($filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function ManualPathInstallerAction($param) {
|
||||
if(Request::IsPost()) {
|
||||
$post = Request::GetAllPost();
|
||||
$controller = $post['controller'];
|
||||
$method = $post['method'];
|
||||
$matchUri = $post['matchUri'];
|
||||
$actionSetText = $post['actionSet'];
|
||||
$paramSet = $post['param'];
|
||||
$module = $post['module'];
|
||||
$actionSet = array();
|
||||
$actionSetText = explode(',', $actionSetText);
|
||||
foreach($actionSetText as $item) {
|
||||
$item = explode(':', $item);
|
||||
if(isset($item[0]) && isset($item[1]) && isset($item[2]))
|
||||
$actionSet[] = array('module'=>$item[0], 'controller'=>$item[1], 'method'=>$item[2]);
|
||||
}
|
||||
$paramText = array();
|
||||
$paramText = explode(',', $paramSet);
|
||||
//Utils::ArrayDisplay($paramText);
|
||||
foreach($paramText as $item) {
|
||||
$item = explode(':', $item);
|
||||
if(isset($item[0]) && isset($item[1]))
|
||||
$paramArray[] = array('var'=>$item[0], 'value'=>$item[1]);
|
||||
}
|
||||
|
||||
$router = new MfRouter();
|
||||
$router->SetController($controller);
|
||||
$router->SetMethod($method);
|
||||
$router->SetUrl($matchUri);
|
||||
$router->SetParam(serialize($paramArray));
|
||||
$router->SetConfig(serialize(array('module'=>$module, 'actionSet'=>$actionSet)));
|
||||
|
||||
MfRouterDAL::Save($router);
|
||||
|
||||
Router::GenerateDbRoutes();
|
||||
}
|
||||
}
|
||||
|
||||
public function PackageInstallerAction($param) {
|
||||
$dir = Config::Get('PATH_CORE').'/modules';
|
||||
$files = scandir($dir);
|
||||
|
||||
$modules = array();
|
||||
foreach($files as $file) {
|
||||
if(preg_match('((.*)(.zip))', $file)) {
|
||||
$modules[] = str_replace('.zip', '', $file);
|
||||
}
|
||||
}
|
||||
|
||||
$this->smarty->assign('modulesList', $modules);
|
||||
|
||||
if(isset($param['package'])) {
|
||||
$installer = new ModuleInstaler($param['package']);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wspolna metoda
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
|
||||
//$this->RunShared('Admin');
|
||||
|
||||
$this->Run($param);
|
||||
//$admin = AuthDAL::GetAdmin();
|
||||
$this->RunShared('Auth', array());
|
||||
$this->smarty->assign('titleAdmin', 'Administracja');
|
||||
$panelMenu = ARRAY_PANEL_MENU;
|
||||
$struct = $panelMenu['admin'];
|
||||
|
||||
$this->smarty->assign('structure',$this->renderStruct($struct));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function renderStruct($struct){
|
||||
$return = '';
|
||||
|
||||
foreach($struct AS $k => $row){
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig',$row).'">'.$k.'</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
192
Admin/controller/SharedController.php
Normal file
192
Admin/controller/SharedController.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/**
|
||||
* $Id: SharedController.php 969 2008-07-29 13:55:14Z pawy $
|
||||
* Kontroller wspolny
|
||||
*
|
||||
*/
|
||||
class SharedController extends MainController implements ControllerInterface {
|
||||
/**
|
||||
* domyslna metoda
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
|
||||
}
|
||||
|
||||
public function infoFrame($param) {
|
||||
$this->smarty->assign('info',$param['info']);
|
||||
$this->smarty->assign('type',$param['type']);
|
||||
}
|
||||
|
||||
public function Pagination($param) {
|
||||
|
||||
if(isset($param['strona']) && $param['strona'] > 0 ){
|
||||
$page = $param['strona'];
|
||||
$URLparam = $this->GetUrlParam($param);
|
||||
}
|
||||
else{
|
||||
$page = 1;
|
||||
$URLtemp = $this->GetUrlParam($param);
|
||||
|
||||
if (!isset($URLtemp[1])) {
|
||||
$URLtemp[1] = '';
|
||||
}
|
||||
|
||||
$URLparam = array($URLtemp[0], $URLtemp[1], 1, 'strona');
|
||||
|
||||
$URLparam = array_merge($URLparam, array_slice($URLtemp, 2));
|
||||
}
|
||||
|
||||
$this->smarty->assign('CurrentPage', $page);
|
||||
|
||||
$URLParam = array("", "");
|
||||
|
||||
$URLParam[0] = $URLparam[3];
|
||||
$URLParam[1] = $URLparam[1] . ',' . $URLparam[0];
|
||||
for ( $i = 4, $size = sizeof($URLparam) ; $i < $size ; $i++)
|
||||
{
|
||||
$URLParam[0] = $URLparam[$i] . ',' . $URLParam[0];
|
||||
}
|
||||
|
||||
$this->smarty->assign("URLParam", $URLParam);
|
||||
|
||||
$this->smarty->assign('pagination', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function Admin($param) {
|
||||
|
||||
$this->smarty->assign('leftBox', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
|
||||
}
|
||||
public function DefaultPanel($param) {
|
||||
$this->smarty->assign('leftBox', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
|
||||
}
|
||||
public function Login($param) {
|
||||
|
||||
$this->smarty->assign('leftBox', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
|
||||
}
|
||||
public function Page($param) {
|
||||
|
||||
$this->smarty->assign('leftBox', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
|
||||
}
|
||||
public function Mailing($param) {
|
||||
|
||||
$this->smarty->assign('leftBox', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
|
||||
}
|
||||
public function News($param) {
|
||||
|
||||
$this->smarty->assign('leftBox', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
|
||||
}
|
||||
public function Offer($param) {
|
||||
|
||||
$this->smarty->assign('leftBox', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
|
||||
}
|
||||
public function Structure($param) {
|
||||
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
$location = SessionProxy::GetValue('location');
|
||||
//Utils::ArrayDisplay($param);
|
||||
$arrayObjStructureMain = StructureDAL::GetTree(array('lang' => $lang, 'type' => 1, 'location' => $location ),array());
|
||||
$arrayObjStructureBottom = StructureDAL::GetTree(array('lang' => $lang, 'type' => 2, 'location' => $location),array());
|
||||
$arrayObjStructureOther = StructureDAL::GetTree(array('lang' => $lang, 'type' => 3, 'location' => $location),array());
|
||||
//$arrayRouter = RouterParamDAL::GetArrayRouter();
|
||||
|
||||
//Utils::ArrayDisplay($arrayObjStructureMain);
|
||||
|
||||
if (isset($param['id'])) {
|
||||
$id = $param['id'];
|
||||
} elseif (isset($param['idElement'])) {
|
||||
$id = $param['idElement'];
|
||||
} else {
|
||||
$id = '';
|
||||
}
|
||||
|
||||
$this->smarty->assign('idStucture', $id);
|
||||
$this->smarty->assign( 'arrayObjStructure' ,$arrayObjStructureMain);
|
||||
$this->smarty->assign( 'arrayObjStructureBottom' ,$arrayObjStructureBottom);
|
||||
$this->smarty->assign( 'arrayObjStructureOther' ,$arrayObjStructureOther);
|
||||
//Utils::ArrayDisplay($this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
$this->partialTemplate = 'StructureModern.tpl';
|
||||
$this->smarty->assign('leftBox', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
|
||||
}
|
||||
|
||||
public function Preferences($param) {
|
||||
|
||||
$this->smarty->assign('leftBox', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
}
|
||||
|
||||
public function StructureAction($param) {
|
||||
//$this->SetAjaxRender();
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
//Utils::ArrayDisplay($param);
|
||||
$arrayObjStructure = StructureDAL::GetTree(array('lang' => $lang),array());
|
||||
//$arrayRouter = RouterParamDAL::GetArrayRouter();
|
||||
|
||||
$this->smarty->assign( 'arrayObjStructure' ,$arrayObjStructure);
|
||||
$this->smarty->assign('leftBox', $this->smarty->fetch($this->templatePath.$this->partialTemplate));
|
||||
|
||||
}
|
||||
|
||||
public function CustomerLink($param) {
|
||||
//$this->SetAjaxRender();
|
||||
|
||||
$lang = SessionProxy::GetValue('lang');
|
||||
//Utils::ArrayDisplay($param);
|
||||
$type = ( isset($param['tagType']) ? $param['tagType'] : " 2 ");
|
||||
$arrayCustomer = Utils::GetArrayList('mf_tag', 'id_mf_tag', 'tag', $lang, ' AND type = '.$type, 'tag');
|
||||
//$arrayRouter = RouterParamDAL::GetArrayRouter();
|
||||
|
||||
$this->smarty->assign('arrayCustomer' ,$arrayCustomer);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Startuje sesje, weryfikuje autoryzacje admina
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Startuje sesje, weryfikuje autoryzacje admina
|
||||
*
|
||||
*/
|
||||
public function Auth($param) {
|
||||
$this->SetNoRender();
|
||||
//session_start();
|
||||
$admin = AuthDAL::GetAdmin();
|
||||
$this->user = $admin;
|
||||
//Utils::ArrayDisplay($this);
|
||||
$this->smarty->assign('admin', $admin);
|
||||
Registry::Set('admin', $admin);
|
||||
if(!is_object($admin)) {
|
||||
//$this->AddRedirectInfo("NIE ZALOGOWANY", null, Router::GenerateUrl('LOGIN', array("Login" => "Index")));
|
||||
die(header("Location: ". Router::GenerateUrl('LOGIN', array("Login" => "Index")) ));
|
||||
//$this->SetActionRedirect('AdminLoginRedirectAction');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Metoda wspolna
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
$this->Run($param);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function postDispatch($param) {
|
||||
}
|
||||
}
|
||||
?>
|
||||
1538
Admin/controller/SimpleArticle/IndexController.php
Normal file
1538
Admin/controller/SimpleArticle/IndexController.php
Normal file
File diff suppressed because it is too large
Load Diff
1375
Admin/controller/SimpleArticle_/IndexController.php
Normal file
1375
Admin/controller/SimpleArticle_/IndexController.php
Normal file
File diff suppressed because it is too large
Load Diff
4043
Admin/controller/StructureController.php
Normal file
4043
Admin/controller/StructureController.php
Normal file
File diff suppressed because it is too large
Load Diff
4007
Admin/controller/StructureController.php_
Normal file
4007
Admin/controller/StructureController.php_
Normal file
File diff suppressed because it is too large
Load Diff
63
Admin/controller/UploaderController.php
Normal file
63
Admin/controller/UploaderController.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Struktura menu
|
||||
*
|
||||
*
|
||||
*/
|
||||
class UploaderController extends MainController implements ControllerInterface {
|
||||
/**
|
||||
* strona glowna
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
}
|
||||
|
||||
public function UploaderAction($param) {
|
||||
|
||||
//Utils::ArrayDisplay($_FILES);
|
||||
if (isset($_FILES['file'])) {
|
||||
move_uploaded_file ( $_FILES['file']['tmp_name'], PATH_STATIC_CONTENT.'temp/'.$_FILES['file']['name'] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function preDispatch($param) {
|
||||
|
||||
$this->AddScript("prototype.js");
|
||||
|
||||
$this->AddScript("GetContent.js");
|
||||
|
||||
$this->AddScript('structure.js');
|
||||
$this->AddScript('Dosia.js');
|
||||
|
||||
$this->AddScript('drag-drop-folder-tree.js');
|
||||
|
||||
$this->AddScript('calendar.js');
|
||||
|
||||
//Utils::ArrayDisplay($param);
|
||||
|
||||
//$this->Run($param);
|
||||
|
||||
|
||||
$arrayModuleName = MfModuleDAL::GetArrayModuleName();
|
||||
$this->smarty->assign( 'arrayModuleName' ,$arrayModuleName);
|
||||
$this->smarty->assign('showIcon', true);
|
||||
//Utils::ArrayDisplay(Utils::ArrayDisplay(SessionProxy::GetValue(EnumSessionValue::USER_OBJECT)));
|
||||
//$this->RunShared('Auth', array());
|
||||
//$this->smarty->assign("menuSelected", "");
|
||||
$this->smarty->assign('activeTab', 'index');
|
||||
$this->AddScript("formAction.js");
|
||||
$this->Run($param);
|
||||
$this->RunShared('Structure', $param);
|
||||
$this->smarty->assign('titleAdmin', 'Struktura strony');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function postDispatch($param) {
|
||||
}
|
||||
}
|
||||
?>
|
||||
738
Admin/controller/UserController.php
Normal file
738
Admin/controller/UserController.php
Normal file
@@ -0,0 +1,738 @@
|
||||
<?php
|
||||
/**
|
||||
* $Id: UserController.php 969 2008-07-29 13:55:14Z pawy $
|
||||
* Zarzadzanie uzytkownikami
|
||||
*
|
||||
*/
|
||||
class UserController extends MainController implements ControllerInterface {
|
||||
|
||||
|
||||
|
||||
// cropper const
|
||||
const PHOTO_ORG_SMALL_SIZE = 70; // minimalny wymiar oryginalnego obrazka
|
||||
const MAX_PHOTO_ORG_FILE_SIZE = 5; // maksymalny rozmiar oryginalnego obrazka w mb
|
||||
|
||||
const CROPPER_MIN_SIZE = 70; // minimalny wymiar croppera
|
||||
const CROPPER_MAX_SIZE = 300; // maksymalny wymiar dla croppera
|
||||
|
||||
const PHOTO_SESSION_NAME = '__avatar_photo_name__';
|
||||
const PHOTO_SESSION_ID = '__avatar_photo_id__';
|
||||
const SIZE_SESSION_NAME = '__avatar_photo_size__';
|
||||
|
||||
const AVATAR_DEST_DIR = 'images/upload/Avatar';
|
||||
const AVATAR_TEMP_DIR = 'images/upload/temp/Avatar';
|
||||
|
||||
const GALLERY_DEST_DIR = 'images/upload/Avatar';
|
||||
const GALLERY_TEMP_DIR = 'images/upload/temp/Avatar';
|
||||
const NO_PHOTO_IMG_BIG = "image/Admin/cropperNoPhotoBig.gif";
|
||||
const NO_PHOTO_IMG_SMALL = "image/Admin/cropperNoPhotoSmall.gif";
|
||||
|
||||
|
||||
/**
|
||||
* Strona glowna
|
||||
*
|
||||
*/
|
||||
public function IndexAction($param) {
|
||||
|
||||
if(isset($param['sort']) && isset($param['direction']))
|
||||
$this->smarty->assign($param['sort'],$param['direction']);
|
||||
else {
|
||||
$param['sort'] = "";
|
||||
$param['direction'] = "";
|
||||
}
|
||||
|
||||
if(isset($param['sort2']) && isset($param['direction2']))
|
||||
$this->smarty->assign($param['sort2'],$param['direction2']);
|
||||
else {
|
||||
$param['sort2'] = "";
|
||||
$param['direction2'] = "";
|
||||
}
|
||||
|
||||
$this->smarty->assign('userList', AdminDAL::GetResult(array(),array(),null,$param['sort'] . " " . $param['direction']));
|
||||
|
||||
|
||||
$this->smarty->assign('archiveUserList', AdminDAL::GetResult(array('archive' => 1),array(),null,$param['sort2'] . " " . $param['direction2']));
|
||||
|
||||
}
|
||||
|
||||
public function JoinAction($param)
|
||||
{
|
||||
if(isset($param['sort']) && isset($param['direction']))
|
||||
$this->smarty->assign($param['sort'],$param['direction']);
|
||||
else
|
||||
{
|
||||
$param['sort'] = "";
|
||||
$param['direction'] = "";
|
||||
}
|
||||
$this->smarty->assign('type',$param['type']);
|
||||
$this->smarty->assign('ids',Request::Get($param['type']));
|
||||
$this->smarty->assign('UserList', AdminDAL::GetResult(array(),array(),null,$param['sort'] . " " . $param['direction']));
|
||||
}
|
||||
|
||||
public function AjaxJoinAction($param)
|
||||
{
|
||||
|
||||
foreach(Request::Get($param['type']) as $key2 => $value2)
|
||||
{
|
||||
MfLinkDAL::DeleteFromLink($value2, $param['type'], null , 'mf_admin');
|
||||
$i = 0;
|
||||
foreach(Request::Get('admin') as $key => $value)
|
||||
{
|
||||
//przypisujemy łączenia
|
||||
$mfLinkObj = new MfLink();
|
||||
$mfLinkObj->SetIdSource($value2);
|
||||
$mfLinkObj->SetSourceType($param['type']);
|
||||
$mfLinkObj->SetIdDestination($value);
|
||||
$mfLinkObj->SetDestinationType('mf_admin');
|
||||
|
||||
MfLinkDAL::Insert($mfLinkObj);
|
||||
$i++;
|
||||
}
|
||||
|
||||
$className = str_replace('mf_','',$param['type']);
|
||||
$className = ucfirst($className);
|
||||
$obj = new $className();
|
||||
$obj->setId($value2);
|
||||
$obj->setAdminCount($i);
|
||||
|
||||
eval($className . 'DAL::Update($obj);');
|
||||
}
|
||||
|
||||
$this->SetAjaxRender();
|
||||
$param['hide']=false;
|
||||
$this->content=$this->FormatAjaxOutput(array(),$param);
|
||||
}
|
||||
|
||||
public function AjaxDeleteAction($param)
|
||||
{
|
||||
|
||||
foreach(Request::Get($param['type']) as $key2 => $value2)
|
||||
{
|
||||
MfLinkDAL::DeleteFromLink($value2, $param['type'], $param['mf_admin'] , 'mf_admin');
|
||||
|
||||
$this->user->SetForumCount($this->user->GetForumCount()-1);
|
||||
AdminDAL::Update($this->user);
|
||||
|
||||
$className = str_replace('mf_','',$param['type']);
|
||||
$className = ucfirst($className);
|
||||
$obj = null;
|
||||
eval('$obj =' .$className . 'DAL::GetById($value2);');
|
||||
$obj->SetAdminCount($obj->GetAdminCount() - 1);
|
||||
|
||||
eval($className . 'DAL::Update($obj);');
|
||||
}
|
||||
|
||||
$this->SetAjaxRender();
|
||||
$param['hide']=false;
|
||||
$this->content=$this->FormatAjaxOutput(array(),$param);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edycja uzytkownika
|
||||
*
|
||||
* @param array $param
|
||||
*/
|
||||
public function EditAction($param) {
|
||||
|
||||
$url = Router::GenerateUrl('UserList',array('User' => 'Index'));
|
||||
|
||||
if(Request::IsPost()) {
|
||||
|
||||
// [login] =>
|
||||
// [password] =>
|
||||
// [passwordconf] =>
|
||||
// [firstName] =>
|
||||
// [lastName] =>
|
||||
// [email] =>
|
||||
// [description] =>
|
||||
// [role] => admin
|
||||
|
||||
$postData = Request::GetAllPost(false);
|
||||
|
||||
$user = AdminDAL::GetById($postData['id']);
|
||||
$user->SetLogin(Request::RemoveXss($postData['login']));
|
||||
$user->SetEmail(Request::RemoveXss($postData['email']));
|
||||
$user->SetFirstName($postData['firstName']);
|
||||
$user->SetLastName($postData['lastName']);
|
||||
$user->SetRole($postData['role']);
|
||||
$user->SetDescription($postData['description']);
|
||||
$pass = trim($postData['password']);
|
||||
|
||||
|
||||
|
||||
//if(Request::GetPost('action') == 'submit' ) {
|
||||
$validator = new Validator($postData);
|
||||
$validator->IsEmpty('login','To pole nie może być puste');
|
||||
|
||||
|
||||
// $validator->IsEmpty('firstName','To pole nie może być puste');
|
||||
// $validator->IsEmpty('lastName', 'To pole nie może być puste');
|
||||
//$validator->IsEmpty('email', 'To pole nie może być puste');
|
||||
//$validator->IsEmpty('role', 'To pole nie może być puste');
|
||||
if ($pass && md5($pass) != $user->GetPassword()) {
|
||||
$validator->IsEmpty('password','To pole nie może być puste');
|
||||
$validator->IsEmpty('passwordconf','To pole nie może być puste');
|
||||
if(Request::GetPost('passwordconf') !== Request::GetPost('password')) {
|
||||
$validator -> AddError('passwordconfDif', 'Hasła są różne');
|
||||
}
|
||||
}
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
|
||||
|
||||
$user->SetPassword(md5($pass));
|
||||
|
||||
if(empty($out)) {
|
||||
$postData = Request::GetAllPost(false);
|
||||
|
||||
$userId = AdminDAL::Save($user);
|
||||
|
||||
|
||||
$this->AddRedirectInfo('Edycja przebiegła pomyślnie.');
|
||||
|
||||
Utils::Redirect($url);
|
||||
|
||||
|
||||
|
||||
}else {
|
||||
//Utils::ArrayDisplay($out);
|
||||
$this->smarty->assign('userData',$user);
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(isset($param['id']) && is_numeric($param['id']) ) {
|
||||
$user = AdminDAL::GetById($param['id']);
|
||||
} else {
|
||||
$user = new Admin();
|
||||
}
|
||||
|
||||
$this->smarty->assign('userData', $user );
|
||||
$this->smarty->assign('userRole', AdminDAL::GetArrayObjRoles());
|
||||
|
||||
}
|
||||
|
||||
public function AjaxEditFormAction($param) {
|
||||
|
||||
|
||||
|
||||
$this -> SetAjaxRender(true);
|
||||
|
||||
if(isset($param['id'])) {
|
||||
$id = $param['id'];
|
||||
SessionProxy::SetValue('editedUser', AdminDAL::GetById($id));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$url = Router::GenerateUrl(array('_value' => 'user'));
|
||||
|
||||
if(Request::IsPost()) {
|
||||
|
||||
if(isset($param['field'])) {
|
||||
$out = $this->ValidateEdit($param);
|
||||
$param['msg'] = 'Pole zostało zwalidowane';
|
||||
$this->content=$this->FormatAjaxOutput($out,$param);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Request::GetPost('action') == 'submit' ) {
|
||||
$out = $this -> ValidateEdit($param);
|
||||
$param['msg'] = 'Twoje zgłoszenie zostało przyjęte';
|
||||
|
||||
if(empty($out) && Request::GetPost('action') == 'submit' ) {
|
||||
$postData = Request::GetAllPost(false);
|
||||
$mail = Request::RemoveXss($postData['email']);
|
||||
|
||||
|
||||
$editedUser = AdminDAL::GetById($id);
|
||||
|
||||
$editedUser->SetEmail(Request::RemoveXss($postData['email']));
|
||||
$editedUser->SetFirstName($postData['firstName']);
|
||||
$editedUser->SetLastName($postData['lastName']);
|
||||
$editedUser->SetRole($postData['role']);
|
||||
$editedUser->SetDescription($postData['description']);
|
||||
|
||||
$photo = SessionProxy::GetValue(self::PHOTO_SESSION_ID);
|
||||
if($photo) {
|
||||
$obj->SetPhotoSrc($photo);
|
||||
SessionProxy::ClearValue(self::PHOTO_SESSION_ID);
|
||||
}
|
||||
|
||||
if(trim(Request::GetPost('password')) != '' && $editedUser->GetPassword() != md5(trim(Request::GetPost('password'))) ) {
|
||||
$pass = trim($postData['password']);
|
||||
$editedUser->SetPassword(md5($pass));
|
||||
}
|
||||
|
||||
$userId = AdminDAL::Save($editedUser);
|
||||
|
||||
|
||||
// $mailer = new Mailer();
|
||||
// $mailer->SendEmail($this->smarty->fetch('partial/Mail/RegisterMail.tpl'), '', 'Rejestracja konta',$postData['email']);
|
||||
|
||||
$this->AddRedirectInfo('Dodawanie użytkownika przebiegło pomyślnie.');
|
||||
|
||||
$param['redirect'] = $url;
|
||||
|
||||
$this->content=$this->FormatAjaxOutput($out,$param);
|
||||
|
||||
}else {
|
||||
$this->content=$this->FormatAjaxOutput($out,$param);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function ValidateEdit($param) {
|
||||
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
|
||||
$user = SessionProxy::GetValue('editedUser');
|
||||
|
||||
if(isset($param['field']) && !Request::Check(ereg_replace('((\[)(.*)(\]))','',urldecode($param['field'])))) {
|
||||
$validator -> AddError($param['field'], $this->GetDictionary('validator_field'));
|
||||
}
|
||||
|
||||
//e-mail
|
||||
if((isset($param['field']) && $param['field'] == 'email') || !isset($param['field']) ) {
|
||||
if($user->GetEmail() != Request::GetPost('email') )
|
||||
$validator -> IsNotInDatabase('email', $this->GetDictionary('validator_email_exist'), 'email');
|
||||
$validator -> IsEmailAddress('email', $this->GetDictionary('validator_email_error'));
|
||||
$validator -> IsEmpty('email',$this->GetDictionary('validator_email_empty'));
|
||||
}
|
||||
|
||||
if((isset($param['field']) && $param['field'] == 'password') || !isset($param['field']) ) {
|
||||
if(trim(Request::GetPost('password')) != '' ) {
|
||||
SessionProxy::SetValue('password',Request::GetPost('password'));
|
||||
$validator -> IsEmpty('password',$this->GetDictionary('validator_password_empty'));
|
||||
}
|
||||
}
|
||||
|
||||
//potwierdzenie hasła
|
||||
if((isset($param['field']) && $param['field'] == 'passwordconf') || !isset($param['field']) ) {
|
||||
if(trim(Request::GetPost('passwordconf')) != '' ) {
|
||||
|
||||
$password = SessionProxy::GetValue('password');
|
||||
if(!is_null($password) && Request::GetPost('passwordconf') !== $password && strlen(Request::GetPost('passwordconf')) > 0) {
|
||||
$validator -> AddError('passwordconf',$this->GetDictionary('validator_password_different'));
|
||||
}
|
||||
$validator -> IsEmpty('passwordconf',$this->GetDictionary('validator_password_empty'));
|
||||
}
|
||||
}
|
||||
|
||||
// if((isset($param['field']) && $param['field'] == 'education') || !isset($param['field']) ) {
|
||||
// $validator -> IsEmpty('education','Nie wybrano wykształcenia','education');
|
||||
// }
|
||||
|
||||
|
||||
// $param['submitForm'] = 'walidacja';
|
||||
return $validator->GetErrorList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dodawanie uzytkownika
|
||||
*
|
||||
* @param array $param
|
||||
*/
|
||||
public function AddAction($param) {
|
||||
|
||||
|
||||
|
||||
|
||||
$url = Router::GenerateUrl('UserList',array('User' => 'Index'));
|
||||
|
||||
//Utils::ArrayDisplay($_POST);
|
||||
|
||||
if(Request::IsPost()) {
|
||||
|
||||
// [login] =>
|
||||
// [password] =>
|
||||
// [passwordconf] =>
|
||||
// [firstName] =>
|
||||
// [lastName] =>
|
||||
// [email] =>
|
||||
// [description] =>
|
||||
// [role] => admin
|
||||
|
||||
$postData = Request::GetAllPost(false);
|
||||
//if(Request::GetPost('action') == 'submit' ) {
|
||||
$validator = new Validator($postData);
|
||||
$validator->IsEmpty('login','To pole nie może być puste');
|
||||
$validator->IsEmpty('password','To pole nie może być puste');
|
||||
$validator->IsEmpty('passwordconf','To pole nie może być puste');
|
||||
$validator->IsEmpty('firstName','To pole nie może być puste');
|
||||
$validator->IsEmpty('lastName', 'To pole nie może być puste');
|
||||
$validator->IsEmpty('email', 'To pole nie może być puste');
|
||||
$validator->IsEmpty('role', 'To pole nie może być puste');
|
||||
if(Request::GetPost('passwordconf') !== Request::GetPost('password')) {
|
||||
$validator -> AddError('passwordconfDif', 'Hasła są róne');
|
||||
}
|
||||
$out = $validator->GetErrorList();
|
||||
|
||||
if(empty($out)) {
|
||||
$postData = Request::GetAllPost(false);
|
||||
$mail = Request::RemoveXss($postData['email']);
|
||||
|
||||
|
||||
$newuser = new Admin();
|
||||
$newuser->SetId(-1);
|
||||
$newuser->SetLogin(Request::RemoveXss($postData['login']));
|
||||
$newuser->SetEmail(Request::RemoveXss($postData['email']));
|
||||
$newuser->SetFirstName($postData['firstName']);
|
||||
$newuser->SetLastName($postData['lastName']);
|
||||
$newuser->SetRole($postData['role']);
|
||||
$newuser->SetDescription($postData['description']);
|
||||
|
||||
$pass = trim($postData['password']);
|
||||
$newuser->SetPassword(md5($pass));
|
||||
|
||||
$userId = AdminDAL::Save($newuser);
|
||||
|
||||
|
||||
$this->AddRedirectInfo('Dodawanie użytkownika przebiegło pomyślnie.');
|
||||
|
||||
Utils::Redirect($url);
|
||||
|
||||
|
||||
|
||||
}else {
|
||||
//Utils::ArrayDisplay($out);
|
||||
$this->smarty->assign('user',$postData);
|
||||
foreach ($out as $item) {
|
||||
$error[$item['field']] = $item['msg'];
|
||||
}
|
||||
$this->smarty->assign('error',$error);
|
||||
|
||||
}
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->smarty->assign('userRole', AdminDAL::GetArrayObjRoles());
|
||||
|
||||
}
|
||||
|
||||
public function AjaxAddFormAction($param) {
|
||||
|
||||
$this -> SetAjaxRender(true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function ValidateAdd($param) {
|
||||
|
||||
$validator = new Validator(Request::GetAllPost());
|
||||
if(isset($param['field']) && !Request::Check(ereg_replace('((\[)(.*)(\]))','',urldecode($param['field'])))) {
|
||||
$validator -> AddError($param['field'], $this->GetDictionary('validator_field'));
|
||||
}
|
||||
|
||||
//e-mail
|
||||
if((isset($param['field']) && $param['field'] == 'email') || !isset($param['field']) ) {
|
||||
|
||||
$validator -> IsNotInDatabase('email', $this->GetDictionary('validator_email_exist'), 'email');
|
||||
$validator -> IsEmailAddress('email', $this->GetDictionary('validator_email_error'));
|
||||
$validator -> IsEmpty('email',$this->GetDictionary('validator_email_empty'));
|
||||
}
|
||||
|
||||
if((isset($param['field']) && $param['field'] == 'password') || !isset($param['field']) ) {
|
||||
SessionProxy::SetValue('password',Request::GetPost('password'));
|
||||
$validator -> IsEmpty('password',$this->GetDictionary('validator_password_empty'));
|
||||
}
|
||||
|
||||
//potwierdzenie hasła
|
||||
if((isset($param['field']) && $param['field'] == 'passwordconf') || !isset($param['field']) ) {
|
||||
|
||||
$password = SessionProxy::GetValue('password');
|
||||
if(!is_null($password) && Request::GetPost('passwordconf') !== $password && strlen(Request::GetPost('passwordconf')) > 0) {
|
||||
$validator -> AddError('passwordconf',$this->GetDictionary('validator_password_different'));
|
||||
}
|
||||
$validator -> IsEmpty('passwordconf',$this->GetDictionary('validator_password_empty'));
|
||||
|
||||
}
|
||||
|
||||
// if((isset($param['field']) && $param['field'] == 'education') || !isset($param['field']) ) {
|
||||
// $validator -> IsEmpty('education','Nie wybrano wykształcenia','education');
|
||||
// }
|
||||
|
||||
|
||||
// $param['submitForm'] = 'walidacja';
|
||||
return $validator->GetErrorList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Usuwanie uzytkownika
|
||||
*
|
||||
* @param array $param
|
||||
*/
|
||||
public function DeleteAction($param) {
|
||||
$this->SetAjaxRender(true);
|
||||
if(isset($param['ok'])) {
|
||||
|
||||
$res = null;
|
||||
if(isset($param['id'])) {
|
||||
$res = AdminDAL::GetById($param['id']);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if(is_object($res)) {
|
||||
AdminDAL::Delete($res);
|
||||
}
|
||||
|
||||
$this->AddRedirectInfo('Użytkownik został usunięty');
|
||||
$this->AddRedirect(Router::GenerateUrl('userIndex', array('User'=>'Index')), 0);
|
||||
|
||||
} else {
|
||||
$buttons = new HtmlButton();
|
||||
$buttons->AddButton('popoverAbort', 'button anuluj lbAction', 'Anuluj', null, 'deactivate');
|
||||
$buttons->AddButton('popoverOk', 'button zapisz', 'Ok', 'document.location.href=\''.Router::GenerateUrl(array('User'=>'Delete', 'id'=>$param['id'], 'ok'=>'1')).'\';', null);
|
||||
$this->content = $this->GeneratePopover('Usuwanie użytkownika', 'usun.gif', 'Czy na pewno chcesz usunąć tego użytkownika?', $buttons->GetElements());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Zmiana hasla
|
||||
*
|
||||
*/
|
||||
public function ChangePasswordAction() {
|
||||
$this->AddScript('prototype.js');
|
||||
$this->AddScript('scriptaculous.js');
|
||||
|
||||
$this->partialTemplate = 'Password.tpl';
|
||||
$this->smarty->assign('msg', '');
|
||||
|
||||
if(isset($_POST['oldPassword']) && isset($_POST['newPassword']) && isset($_POST['confirmPassword'])) {
|
||||
$admin = AuthDAL::GetAdmin();
|
||||
if(AdminDAL::CheckPassword($admin->GetId(), $_POST['oldPassword'])) {
|
||||
AdminDAL::UpdatePassword($admin->GetId(), $_POST['newPassword'], $_POST['oldPassword']);
|
||||
$this->smarty->assign('msg', 'Hasło zostało zmienione');
|
||||
} else {
|
||||
$this->smarty->assign('msg', 'Podano nieprawidłowe hasło. Spróbuj ponownie.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wspolna metoda
|
||||
*
|
||||
*/
|
||||
public function preDispatch($param) {
|
||||
$this->RunShared('Auth', $param);
|
||||
$this->Run($param);
|
||||
$admin = AuthDAL::GetAdmin();
|
||||
$this->user = $admin;
|
||||
|
||||
$this->smarty->assign('titleAdmin', 'Administracja');
|
||||
|
||||
$panelMenu = ARRAY_PANEL_MENU;
|
||||
$struct = $panelMenu['admin'];
|
||||
|
||||
$this->smarty->assign('structure',$this->renderStruct($struct));
|
||||
|
||||
}
|
||||
|
||||
private function renderStruct($struct){
|
||||
$return = '';
|
||||
|
||||
foreach($struct AS $k => $row){
|
||||
$return .= '<li><a href="' . Router::GenerateUrl('dictpig',$row).'">'.$k.'</a></li>';
|
||||
}
|
||||
|
||||
$html = '<ul>';
|
||||
$html .= $return;
|
||||
$html .= '</ul>';
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function postDispatch($param) {
|
||||
|
||||
}
|
||||
|
||||
// cropper
|
||||
// cropper //
|
||||
|
||||
public function AjaxPhotoCropperAction($param) {
|
||||
$this->SetAjaxRender();
|
||||
|
||||
$photoPath = Request::GetPost('photoPath');
|
||||
$photoHeight = Request::GetPost('photoHeight');
|
||||
$photoWidth = Request::GetPost('photoWidth');
|
||||
|
||||
$this->smarty->assign('photoWidth', $photoWidth);
|
||||
$this->smarty->assign('photoHeight', $photoHeight);
|
||||
|
||||
$this->smarty->assign('minPhotoWidth', self::CROPPER_MIN_SIZE);
|
||||
$this->smarty->assign('minPhotoHeight', self::CROPPER_MIN_SIZE);
|
||||
|
||||
$this->smarty->assign('noPhotoImgBig', URL_STATIC_CONTENT . URL_DELIMITER . self::NO_PHOTO_IMG_BIG);
|
||||
$this->smarty->assign('noPhotoImgSmall', URL_STATIC_CONTENT . URL_DELIMITER . self::NO_PHOTO_IMG_SMALL);
|
||||
|
||||
$this->smarty->assign('photoPath', Request::GetPost('photoPath'));
|
||||
if (isset($param['id'])) {
|
||||
$this->smarty->assign('cutUrl', array('user' => 'AjaxPhotoCropped', 'id' => $param['id']));
|
||||
} else {
|
||||
$this->smarty->assign('cutUrl', array('user' => 'AjaxPhotoCropped'));
|
||||
}
|
||||
|
||||
$this->smarty->assign('fields',
|
||||
array(
|
||||
0 => array('name'=>'colSize', 'type'=>'radio', 'value'=>1, 'label'=>'pół kolumny', 'options'=>'checked="checked"'),
|
||||
1 => array('name'=>'colSize', 'type'=>'radio', 'value'=>2, 'label'=>'cała kolumna', 'options'=>''),
|
||||
2 => array('name'=>'colSize', 'type'=>'radio', 'value'=>3, 'label'=>'bez skalowania', 'options'=>''),
|
||||
)
|
||||
);
|
||||
|
||||
$this->smarty->assign('uploadUrl', array('user' => 'AjaxPhotoUpload'));
|
||||
}
|
||||
|
||||
public function AjaxPhotoCroppedAction($param) {
|
||||
$upload = true;
|
||||
$oldPhoto = null;
|
||||
|
||||
|
||||
$redirect = 'self';
|
||||
$this->SetAjaxRender();
|
||||
|
||||
$photoFile = SessionProxy::GetValue(self::PHOTO_SESSION_NAME);
|
||||
SessionProxy::ClearValue(self::PHOTO_SESSION_NAME);
|
||||
$tmpPhotoArray = array();
|
||||
$tmpPhotoArray['name'] = $photoFile . '.' . PhotoDAL::PHOTO_NEW_EXT;
|
||||
$tmpPhotoArray['tmp_name'] = Config::Get('PATH_STATIC_CONTENT') . self::GALLERY_TEMP_DIR . DIRECTORY_SEPARATOR . $tmpPhotoArray['name'];
|
||||
|
||||
$croppSize = SessionProxy::GetValue(self::SIZE_SESSION_NAME);
|
||||
SessionProxy::ClearValue(self::SIZE_SESSION_NAME);
|
||||
$orgSize = getimagesize($tmpPhotoArray['tmp_name']);
|
||||
|
||||
$sc = 1;
|
||||
if($upload) {
|
||||
if($orgSize[0] != $croppSize['w']) {
|
||||
$sc = $orgSize[0]/$croppSize['w'];
|
||||
}
|
||||
} else {
|
||||
$cs = getimagesize(Config::Get('PATH_STATIC_CONTENT') . self::GALLERY_TEMP_DIR . DIRECTORY_SEPARATOR . $oldPhoto[0]->GetPhoto('temp') . '.' . PhotoDAL::PHOTO_NEW_EXT);
|
||||
if($orgSize[0] != $cs[0]) {
|
||||
$sc = $orgSize[0] / $cs[0];
|
||||
}
|
||||
}
|
||||
|
||||
$croppArray = array(
|
||||
'x' => Request::Get('x') * $sc,
|
||||
'y' => Request::Get('y') * $sc,
|
||||
'w' => Request::Get('w') * $sc,
|
||||
'h' => Request::Get('h') * $sc
|
||||
);
|
||||
|
||||
$destDir = self::GALLERY_DEST_DIR;
|
||||
|
||||
|
||||
$photo = PhotoDAL::ExtSimplePhotoUpload($tmpPhotoArray, $destDir, 'user', null, null, $croppArray);
|
||||
|
||||
$id = null;
|
||||
|
||||
// $objPhoto = new Picture();
|
||||
// $objPhoto->SetLink($photoFile);
|
||||
// $idPhoto = PictureDAL::Insert($objPhoto);
|
||||
if (isset($param['id'])) {
|
||||
|
||||
$admin = AdminDAL::GetById($param['id']);
|
||||
$admin->SetPhotoSrc($photoFile);
|
||||
AdminDAL::Save($admin);
|
||||
|
||||
// $articleObj = MfArticleDAL::GetById($param['id']);
|
||||
// $articleObj->SetIdPicture($idPhoto);
|
||||
// MfArticleDAL::Save($articleObj);
|
||||
} else {
|
||||
SessionProxy::SetValue(self::PHOTO_SESSION_ID, $photoFile);
|
||||
}
|
||||
|
||||
if(isset($param['id'])) {
|
||||
$redirect = Router::GenerateUrl(array('user'=>'Edit', 'id'=>$param['id']));
|
||||
} else {
|
||||
$redirect = Router::GenerateUrl(array('user'=>'Edit'));
|
||||
}
|
||||
$this->smarty->assign('photoPath', $photoFile);
|
||||
$this->smarty->assign('redirect', null);
|
||||
}
|
||||
|
||||
public function AjaxPhotoUploadAction($param) {
|
||||
|
||||
$this->SetAjaxRender();
|
||||
$photoFile = $_FILES['photo']['tmp_name'];
|
||||
$photoSize = getimagesize($photoFile);
|
||||
|
||||
if ($photoSize[0] < self::PHOTO_ORG_SMALL_SIZE) {
|
||||
$error = "Szerokość zdjęcia jest zbyt mała.";
|
||||
} else if($photoSize[1] < self::PHOTO_ORG_SMALL_SIZE) {
|
||||
$error = "Wysokość zdjęcia jest zbyt mała.";
|
||||
} else if (filesize($photoFile) > (self::MAX_PHOTO_ORG_FILE_SIZE*1048576)) {
|
||||
$error = "Przekroczony rozmiar zdjęcia(max: " . self::MAX_PHOTO_ORG_FILE_SIZE . "MB).";
|
||||
}
|
||||
|
||||
if (!MimeType::IsImage($_FILES['photo'])) {
|
||||
$error = "Podany przez ciebie plik ma niepoprawny format.";
|
||||
}
|
||||
|
||||
if (isset($error)) {
|
||||
$this->smarty->assign('error', $error);
|
||||
} else {
|
||||
|
||||
$photoProp = $photoSize[0] / $photoSize[1];
|
||||
|
||||
$photoWidth = $photoSize[0];
|
||||
$photoHeight = $photoSize[1];
|
||||
|
||||
|
||||
if ($photoWidth > self::CROPPER_MAX_SIZE) {
|
||||
$photoHeight = self::CROPPER_MAX_SIZE / $photoProp;
|
||||
$photoWidth = self::CROPPER_MAX_SIZE;
|
||||
}
|
||||
|
||||
if ($photoHeight > self::CROPPER_MAX_SIZE) {
|
||||
$photoWidth = self::CROPPER_MAX_SIZE * $photoProp;
|
||||
$photoHeight = self::CROPPER_MAX_SIZE;
|
||||
}
|
||||
|
||||
$newName = md5(time());
|
||||
SessionProxy::SetValue(self::PHOTO_SESSION_NAME, $newName);
|
||||
SessionProxy::SetValue(self::SIZE_SESSION_NAME, array('w' => $photoWidth, 'h' => $photoHeight));
|
||||
|
||||
$photoFile = PhotoDAL::ExtSimplePhotoUpload($_FILES['photo'], self::GALLERY_TEMP_DIR , 'gallery_cropp_temporary', $newName, 'temp');
|
||||
$photoFile = self::GALLERY_TEMP_DIR . URL_DELIMITER . $photoFile;
|
||||
|
||||
$this->smarty->assign('page2load', Router::GenerateUrl(array('zdjecia' => 'edycja')));
|
||||
$this->smarty->assign('photoFile', $photoFile);
|
||||
$this->smarty->assign('photoWidth', (int)$photoWidth);
|
||||
$this->smarty->assign('photoHeight', (int)$photoHeight);
|
||||
$this->smarty->assign('onFly', (Request::Check('onFly') ? 'true' : 'false'));
|
||||
$this->smarty->assign('cropPrefix', Request::GetPost('cropPrefix'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
?>
|
||||
366
Admin/controller/UtilsController.php
Normal file
366
Admin/controller/UtilsController.php
Normal file
@@ -0,0 +1,366 @@
|
||||
<?
|
||||
class UtilsController extends MainController implements ControllerInterface
|
||||
{
|
||||
|
||||
|
||||
public function IndexAction($param){
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sote DEcrypt User Data
|
||||
*
|
||||
*
|
||||
*/
|
||||
function TestDecryptAction($param) {
|
||||
|
||||
if (function_exists("mcrypt_module_open"))
|
||||
{
|
||||
Utils::ArrayDisplay('jest');
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils::ArrayDisplay('nie ma');
|
||||
}
|
||||
$encrypted = "8rJL4bjQiv+qO2s2q3VVZwQuqfo=";
|
||||
$shopLicence = "2021-0924-0001-5422-e032-c32f";
|
||||
$key = md5($shopLicence);
|
||||
|
||||
$string = $encrypted;
|
||||
Utils::ArrayDisplay("baza: ".$string);
|
||||
$string = base64_decode($encrypted);
|
||||
Utils::ArrayDisplay("base64_decode: ".$string);
|
||||
/* Open module, and create IV */
|
||||
$td = mcrypt_module_open('des', '', 'cfb', '');
|
||||
Utils::ArrayDisplay($td);
|
||||
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
|
||||
Utils::ArrayDisplay($key);
|
||||
$iv_size = mcrypt_enc_get_iv_size($td);
|
||||
$iv = substr($string, 0, $iv_size);
|
||||
$string = substr($string, $iv_size);
|
||||
Utils::ArrayDisplay("base64_decode: ".$string);
|
||||
/* Initialize encryption handle */
|
||||
if (mcrypt_generic_init($td, $key, $iv) != -1)
|
||||
{
|
||||
|
||||
/* Encrypt data */
|
||||
$c_t = @mdecrypt_generic($td, $string);
|
||||
Utils::ArrayDisplay("Encrypt data: ".$c_t);
|
||||
mcrypt_generic_deinit($td);
|
||||
mcrypt_module_close($td);
|
||||
|
||||
Utils::ArrayDisplay($c_t);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Sote DEcrypt User Data
|
||||
*
|
||||
*
|
||||
*/
|
||||
function TestEncryptAction($param) {
|
||||
|
||||
if (function_exists("mcrypt_module_open"))
|
||||
{
|
||||
Utils::ArrayDisplay('jest');
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils::ArrayDisplay('nie ma');
|
||||
}
|
||||
$toEncrypt = "Skrzyszów 97a";
|
||||
$shopLicence = "2013-0419-0001-3329-52c4-440b";
|
||||
$key = md5($shopLicence);
|
||||
|
||||
$string = $toEncrypt;
|
||||
|
||||
/* Open module, and create IV */
|
||||
$td = mcrypt_module_open('des', '', 'cfb', '');
|
||||
$key = substr($key, 0, mcrypt_enc_get_key_size($td));
|
||||
$iv_size = mcrypt_enc_get_iv_size($td);
|
||||
$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);
|
||||
|
||||
/* Initialize encryption handle */
|
||||
if (mcrypt_generic_init($td, $key, $iv) != -1)
|
||||
{
|
||||
|
||||
/* Encrypt data */
|
||||
/**
|
||||
* Hack for warning error message that $string is empty.
|
||||
*/
|
||||
if (empty($string))
|
||||
$c_t = @mcrypt_generic($td, $string);
|
||||
else
|
||||
$c_t = mcrypt_generic($td, $string);
|
||||
mcrypt_generic_deinit($td);
|
||||
mcrypt_module_close($td);
|
||||
$c_t = $iv . $c_t;
|
||||
|
||||
$decrypted = base64_encode($c_t);
|
||||
Utils::ArrayDisplay($decrypted);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function DecryptUserDataAction($param) {
|
||||
|
||||
$dalData = StUserDataDAL::GetDalDataObj();
|
||||
$dalData->setCondition(array());
|
||||
//$dalData->setLimit(10);
|
||||
|
||||
|
||||
$arrayObj = StUserDataDAL::GetResult($dalData);
|
||||
|
||||
//Utils::ArrayDisplay($arrayObj);
|
||||
$arrayObjDescrypted = array();
|
||||
/*
|
||||
* dekodowanie ze starej wersji
|
||||
*
|
||||
*
|
||||
*/
|
||||
foreach ($arrayObj as $obj) {
|
||||
$obj->SetAddress(StUserData::Decrypt($obj->getAddress()));
|
||||
$obj->SetaddressMore(StUserData::Decrypt($obj->getaddressMore()));
|
||||
$obj->Setcode(StUserData::Decrypt($obj->getcode()));
|
||||
$obj->Setcompany(StUserData::Decrypt($obj->getcompany()));
|
||||
$obj->Setflat(StUserData::Decrypt($obj->getflat()));
|
||||
$obj->Sethouse(StUserData::Decrypt($obj->gethouse()));
|
||||
$obj->Setpesel(StUserData::Decrypt($obj->getpesel()));
|
||||
$obj->Setphone(StUserData::Decrypt($obj->getphone()));
|
||||
$obj->Setregion(StUserData::Decrypt($obj->getregion()));
|
||||
$obj->Setstreet(StUserData::Decrypt($obj->getstreet()));
|
||||
$obj->Settown(StUserData::Decrypt($obj->gettown()));
|
||||
|
||||
$arrayObjDescrypted[] = $obj;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Kodowaie do nowej wersji
|
||||
*
|
||||
*
|
||||
*/
|
||||
$arrayObjEncrypted = array();
|
||||
foreach ($arrayObjDescrypted as $obj) {
|
||||
// $obj->SetAddress(StUserData::Encrypt($obj->getAddress()));
|
||||
// $obj->SetaddressMore(StUserData::Encrypt($obj->getaddressMore()));
|
||||
// $obj->Setcode(StUserData::Encrypt($obj->getcode()));
|
||||
// $obj->Setcompany(StUserData::Encrypt($obj->getcompany()));
|
||||
// $obj->Setflat(StUserData::Encrypt($obj->getflat()));
|
||||
// $obj->Sethouse(StUserData::Encrypt($obj->gethouse()));
|
||||
// $obj->Setpesel(StUserData::Encrypt($obj->getpesel()));
|
||||
// $obj->Setphone(StUserData::Encrypt($obj->getphone()));
|
||||
// $obj->Setregion(StUserData::Encrypt($obj->getregion()));
|
||||
// $obj->Setstreet(StUserData::Encrypt($obj->getstreet()));
|
||||
// $obj->Settown(StUserData::Encrypt($obj->gettown()));
|
||||
// $obj->setUpdatedAt(Utils::GetNowDate());
|
||||
StUserDataDAL::Save($obj);
|
||||
$arrayObjEncrypted[] = $obj;
|
||||
|
||||
}
|
||||
Utils::ArrayDisplay($arrayObjDescrypted);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function GenerateModAction($param) {
|
||||
MFLog::Info(__FUNCTION__);
|
||||
//require_once('../core/lib/Smarty/Smarty.class.php');
|
||||
//$smarty = new Smarty();
|
||||
// $smarty->template_dir = Config::Get('PATH_SMARTY_TEMPLATE');
|
||||
// $smarty->compile_dir = Config::Get('PATH_SMARTY_COMPILE');
|
||||
|
||||
$db = Registry::Get('db');
|
||||
|
||||
$sql = " select table_name from information_schema.tables where table_schema <> 'information_schema' ";
|
||||
$stmt = $db->prepare($sql)
|
||||
->execute($sql);
|
||||
|
||||
$tables = $stmt->FetchAllRow();
|
||||
foreach ($tables as $table) {
|
||||
|
||||
$tableName = $table[0];
|
||||
$className = ucfirst(Utils::SQLName2PHPName($tableName));
|
||||
|
||||
$this->smarty->assign('tableName', $tableName);
|
||||
$this->smarty->assign('className', $className);
|
||||
|
||||
// zależne obiekty/tabele działa dopiero od mySQL 5.1.16
|
||||
// $sql = " select table_name from referential_constraints where constraint_schema <> 'information_schema' and referenced_table_name = '$tableName' ";
|
||||
// $stmt = $db->prepare($sql)
|
||||
// ->execute($sql);
|
||||
//
|
||||
// $refTableNames = array();
|
||||
//
|
||||
// $refTables = $stmt->FetchAllRow();
|
||||
// foreach ($refTables as $refTable) {
|
||||
// $tmp_name = Utils::SQLName2PHPName($refTable[0]);
|
||||
// $refTables[$refTable[0]] = $tmp_name;
|
||||
// }
|
||||
//
|
||||
// $smarty->assign('refTables', $refTables);
|
||||
// kolumny tabeli dla obiektu
|
||||
|
||||
$sql = " select column_name from information_schema.columns where table_name='$tableName'; ";
|
||||
$stmt = $db->prepare($sql)
|
||||
->execute($sql);
|
||||
|
||||
|
||||
$columnNames = array();
|
||||
|
||||
|
||||
$columns = $stmt->FetchAllRow();
|
||||
foreach ($columns as $column) {
|
||||
if ($column[0] === 'id_' . $tableName) {
|
||||
$tmp_name = 'id';
|
||||
} else {
|
||||
$tmp_name = Utils::SQLName2PHPName($column[0]);
|
||||
}
|
||||
$columnNames[$column[0]] = $tmp_name;
|
||||
}
|
||||
|
||||
|
||||
$this->smarty->assign('columnNames', $columnNames);
|
||||
|
||||
$output = '<?php' . $this->smarty->fetch('templateModel.tpl') . '?>';
|
||||
$file = fopen(PATH_MODEL_TMP . $className . '.class.php', "w");
|
||||
fwrite($file, $output);
|
||||
fclose($file);
|
||||
|
||||
$outputDAL = '<?php' . $this->smarty->fetch('templateModelDAL.tpl') . '?>';
|
||||
$file = fopen(PATH_MODEL_TMP . $className . 'DAL.class.php', "w");
|
||||
fwrite($file, $outputDAL);
|
||||
fclose($file);
|
||||
}
|
||||
}
|
||||
|
||||
public function GenOneModelAction($param) {
|
||||
// kolumny tabeli dla obiektu
|
||||
|
||||
$tableName = 'st_user_data';
|
||||
|
||||
$db = Registry::Get('db');
|
||||
$sql = " select column_name from information_schema.columns where table_name='$tableName'; ";
|
||||
$stmt = $db->prepare($sql)
|
||||
->execute($sql);
|
||||
|
||||
$className = ucfirst(Utils::SQLName2PHPName($tableName));
|
||||
|
||||
$this->smarty->assign('tableName', $tableName);
|
||||
$this->smarty->assign('className', $className);
|
||||
|
||||
$columnNames = array();
|
||||
$columns = $stmt->fetchAllAssoc();
|
||||
//Utils::ArrayDisplay($columns);
|
||||
//$columns = $stmt->FetchAllRow();
|
||||
foreach ($columns as $column) {
|
||||
//Utils::ArrayDisplay($column);
|
||||
if ($column['COLUMN_NAME'] === 'id_mf_participant') {
|
||||
$tmp_name = 'id';
|
||||
} else {
|
||||
$tmp_name = Utils::SQLName2PHPName($column['COLUMN_NAME']);
|
||||
}
|
||||
$columnNames[$column['COLUMN_NAME']] = $tmp_name;
|
||||
}
|
||||
//Utils::ArrayDisplay($this->smarty);
|
||||
|
||||
$this->smarty->assign('columnNames', $columnNames);
|
||||
|
||||
$output = '<?php' . $this->smarty->fetch('partial/Utils/templateModel.tpl') . '?>';
|
||||
//Utils::ArrayDisplay($this->smarty);
|
||||
$file = fopen(PATH_MODEL_TMP . $className . '.class.php', "w");
|
||||
fwrite($file, $output);
|
||||
fclose($file);
|
||||
|
||||
$outputDAL = '<?php' . $this->smarty->fetch('partial/Utils/templateModelDAL.tpl') . '?>';
|
||||
//Utils::ArrayDisplay($outputDAL);
|
||||
$file = fopen(PATH_MODEL_TMP . $className . 'DAL.class.php', "w");
|
||||
fwrite($file, $outputDAL);
|
||||
fclose($file);
|
||||
|
||||
}
|
||||
|
||||
public function UpdateFieldAction($param) {
|
||||
|
||||
|
||||
$arrayTableField = array(
|
||||
'mf_article_description' => array('description', 'shortnote'),
|
||||
'mf_dictionary' => array('replacement'),
|
||||
'mf_article_box' => array('description', 'shortnote'),
|
||||
'st_webpage' => array('opt_other_link', 'opt_content'),
|
||||
'st_webpage_i18n' => array('other_link', 'content')
|
||||
);
|
||||
|
||||
$stringToReplace = 'https://aem.hean.pl';
|
||||
$stringReplace = 'https://hean.pl';
|
||||
|
||||
|
||||
foreach ($arrayTableField as $table => $arrayField) {
|
||||
//$table = '';
|
||||
foreach ($arrayField as $field) {
|
||||
|
||||
$sql = "UPDATE $table SET $field = REPLACE($field, '$stringToReplace', '$stringReplace') WHERE $field LIKE '%$stringToReplace%'";
|
||||
Utils::ArrayDisplay($sql);
|
||||
// $db = Registry::Get('db');
|
||||
// $stmt = $db->prepare($sql)->execute($sql);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* preDispatch
|
||||
* @param array $param
|
||||
* @return null
|
||||
*/
|
||||
public function preDispatch($param){
|
||||
$this->Run($param);
|
||||
$this->AddScript('dropDown.js');
|
||||
$this->AddScript('structure.js');
|
||||
$this->AddScript('Dosia.js');
|
||||
$this->AddScript('Link.js');
|
||||
$this->AddScript('drag-drop-folder-tree.js');
|
||||
// //$this->AddScript('Validator.js');
|
||||
$this->AddScript('calendar.js');
|
||||
|
||||
$this->RunShared('Auth', array());
|
||||
|
||||
$this->RunShared('Structure', $param);
|
||||
$this->smarty->assign('idStucture', SessionProxy::GetValue('idStructure'));
|
||||
|
||||
$this->smarty->assign('lang', 'pl');
|
||||
$this->smarty->assign('titleAdmin', 'Pliki');
|
||||
$this->smarty->assign('activeTab', 'index');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* postDispatch
|
||||
* @param array $param
|
||||
* @return null
|
||||
*/
|
||||
public function postDispatch($param){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
1
Admin/error.html
Normal file
1
Admin/error.html
Normal file
@@ -0,0 +1 @@
|
||||
ERROR 404
|
||||
70
Admin/index.php
Normal file
70
Admin/index.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
ini_set('default_charset','utf-8');
|
||||
include('../core/core.php');
|
||||
|
||||
|
||||
|
||||
|
||||
ini_set("display_errors" ,true);
|
||||
|
||||
|
||||
/**
|
||||
* Autoloader klas
|
||||
*
|
||||
* @param unknown_type $className
|
||||
*/
|
||||
spl_autoload_register(function ($className) {
|
||||
//echo $className;
|
||||
Core::LoadClass($className);
|
||||
});
|
||||
Core::Init(PageType::ADMIN);
|
||||
|
||||
//$logger = LoggerManager::getLogger(isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : __FILE__);
|
||||
Core::LoadSmarty();
|
||||
session_start();
|
||||
$scripts = array();
|
||||
|
||||
Registry::Set('javascript', $scripts);
|
||||
|
||||
//Router::AddRoute('addStructure','Structure/Add', array('controller'=>'StructureController', 'method'=>'Add', 'push' => array('paramStr' => true), 'config'=>array('actionSet'=>array())));
|
||||
Router::AddRoute('addStructure','Structure/Add', array('controller'=>'StructureController', 'method'=>'ModernAdd', 'push' => array('paramStr' => true), 'config'=>array('actionSet'=>array())));
|
||||
Router::AddRoute('editStructure','Structure/Edit/id/:id', array('controller'=>'StructureController', 'method'=>'ModernEdit', 'push' => array('paramStr' => true), 'config'=>array('actionSet'=>array())));
|
||||
Router::AddRoute('copyStructure','Structure/Copy/id/:id', array('controller'=>'StructureController', 'method'=>'Copy', 'push' => array('paramStr' => true), 'config'=>array('actionSet'=>array())));
|
||||
Router::AddRoute('customerEditpl', 'customer/gallery/pl', array('controller'=>'StructureController', 'method'=>'Edit', 'push' => array('id' => 18, 'lang' => 'pl'), 'config'=>array('actionSet'=>array())));
|
||||
Router::AddRoute('customerEditen', 'customer/gallery/en', array('controller'=>'StructureController', 'method'=>'Edit', 'push' => array('id' => 52, 'lang' => 'en'), 'config'=>array('actionSet'=>array())));
|
||||
Router::AddRoute('customerEditru', 'customer/gallery/ru', array('controller'=>'StructureController', 'method'=>'Edit', 'push' => array('id' => 30, 'lang' => 'ru'), 'config'=>array('actionSet'=>array())));
|
||||
Router::AddRoute('customerEditde', 'customer/gallery/de', array('controller'=>'StructureController', 'method'=>'Edit', 'push' => array('id' => 40, 'lang' => 'de'), 'config'=>array('actionSet'=>array())));
|
||||
//Router::AddRoute('HomeSite','HomeSite', array('controller'=>'SimpleArticle_Index', 'method'=>'Edit', 'push' => array('idArticle' => 3 , 'paramStr' => true), 'config'=>array('actionSet'=>array())));
|
||||
//Router::AddRoute('SaveStructure','Structure/Save', array('controller'=>'StructureController', 'method'=>'Save', 'push' => array('paramStr' => true), 'config'=>array('actionSet'=>array(array('module'=>'SimpleArticle', 'controller'=>'SimpleArticle_IndexController', 'method'=>'EditStructureAction')))));
|
||||
//Router::AddRoute('indexStructure','Structure', array('controller'=>'StructureController', 'method'=>'Index', 'push' => array()));
|
||||
|
||||
|
||||
|
||||
Router::$controllerMethodSeek = false;
|
||||
Router::$popParamUnpaired = false;
|
||||
Router::$reverseRoute = true;
|
||||
Router::$parseLang = false;
|
||||
Router::$pathParsed = false;
|
||||
|
||||
if (SessionProxy::GetValue('lang')) {
|
||||
Router::$curLang=SessionProxy::GetValue('lang');
|
||||
//Utils::ArrayDisplay(Router::$curLang);
|
||||
//Router::$curLang = $param['lang'];
|
||||
}
|
||||
//Utils::ArrayDisplay($_SESSION);
|
||||
|
||||
$front = new FrontController();
|
||||
|
||||
$front->SetTitleDelimiter(' - ');
|
||||
$front->AddTitle('Administracja');
|
||||
$front->AddTitle(PROJECT_NAME);
|
||||
|
||||
|
||||
$front->FlipTitle();
|
||||
|
||||
$front->Dispatch();
|
||||
|
||||
Core::Garbage();
|
||||
//$_SESSION[SESSION_PATH_KEY] = PATH_STATIC_CONTENT;
|
||||
//Utils::ArrayDisplay($_SESSION);
|
||||
?>
|
||||
364
Admin/module/Admin.mod.php
Normal file
364
Admin/module/Admin.mod.php
Normal file
@@ -0,0 +1,364 @@
|
||||
<?
|
||||
|
||||
/**
|
||||
* $Id: Admin.mod.php 703 2008-06-26 11:15:09Z pawy $
|
||||
* Klasa przechowujaca dane zalogowanego admina
|
||||
*
|
||||
*/
|
||||
class Admin extends DataObject {
|
||||
|
||||
const SMARTY_NAME = 'admin';
|
||||
const SMARTY_DEFAULT_ACCESS = 'admin';
|
||||
|
||||
|
||||
static $tableName = 'mf_admin';
|
||||
static $classTablePK = 'id_mf_admin';
|
||||
|
||||
static $className = __CLASS__;
|
||||
|
||||
|
||||
static $fields = array(
|
||||
'id_mf_admin' => 'id',
|
||||
'email' => 'email',
|
||||
'first_name' => 'firstName',
|
||||
'last_name' => 'lastName',
|
||||
'login' => 'login',
|
||||
'password' => 'password',
|
||||
'role' => 'role',
|
||||
'last_login' => 'lastLogin',
|
||||
'description' => 'description',
|
||||
'online' => 'online',
|
||||
'last_activity' => 'lastActivity',
|
||||
'phone' => 'phone',
|
||||
'authorized' => 'authorized',
|
||||
'photo_src' => 'photoSrc',
|
||||
'forum_count' => 'forumCount',
|
||||
'_create_time' => 'createTime',
|
||||
'moderated_post_count' => 'moderatedPostCount',
|
||||
'archive' => 'archive',
|
||||
'delete_time' => 'deleteTime'
|
||||
);
|
||||
|
||||
|
||||
public function GetTableName(){
|
||||
return self::$tableName;
|
||||
}
|
||||
|
||||
public function GetFields(){
|
||||
return self::$fields;
|
||||
}
|
||||
|
||||
public function GetClassName(){
|
||||
return self::$className;
|
||||
}
|
||||
|
||||
|
||||
public function GetClassTablePK() {
|
||||
return self::$classTablePK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* id admnina
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $id;
|
||||
/**
|
||||
* email admina
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $email;
|
||||
/**
|
||||
* Imie i nazwisko admina
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $firstName;
|
||||
private $lastName;
|
||||
/**
|
||||
* login admina
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $login;
|
||||
private $password;
|
||||
/**
|
||||
* Rola admina
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
||||
private $role;
|
||||
/**
|
||||
* Szablon uprawnien
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $access;
|
||||
/**
|
||||
* Data i godzina ostatniego logowania
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $lastLogin;
|
||||
|
||||
private $online;
|
||||
private $lastActivity;
|
||||
|
||||
private $phone;
|
||||
|
||||
private $description;
|
||||
|
||||
private $authorized;
|
||||
|
||||
private $photoSrc;
|
||||
|
||||
private $forumCount;
|
||||
|
||||
private $createTime;
|
||||
private $moderatedPostCount;
|
||||
|
||||
private $archive;
|
||||
private $deleteTime;
|
||||
|
||||
function __construct($id = -1, $description = null, $email = null, $firstName = null, $lastName = null, $login = null, $password = null, $role = null, $access = null, $lastLogin = null, $online = null, $phone = null, $authorized = null, $moderatedPostCount = null,$archive =null) {
|
||||
$this->id = $id;
|
||||
$this->description = $description;
|
||||
$this->email = $email;
|
||||
$this->firstName = $firstName;
|
||||
$this->lastName = $lastName;
|
||||
$this->login = $login;
|
||||
$this->role = $role;
|
||||
$this->access = $access;
|
||||
$this->lastLogin = $lastLogin;
|
||||
$this->online = $online;
|
||||
$this->phone = $phone;
|
||||
$this->authorized = $authorized;
|
||||
$this->moderatedPostCount = $moderatedPostCount;
|
||||
$this->archive = $archive;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getModeratedPostCount() {
|
||||
return $this->moderatedPostCount;
|
||||
}
|
||||
|
||||
public function setModeratedPostCount($moderatedPostCount) {
|
||||
$this->moderatedPostCount = $moderatedPostCount;
|
||||
}
|
||||
|
||||
public function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId($id) {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getEmail() {
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function setEmail($email) {
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->firstName . " " . $this->lastName;
|
||||
}
|
||||
|
||||
public function getFirstName() {
|
||||
return $this->firstName;
|
||||
}
|
||||
|
||||
public function setFirstName($firstName) {
|
||||
$this->firstName = $firstName;
|
||||
}
|
||||
|
||||
public function getLastName() {
|
||||
return $this->lastName;
|
||||
}
|
||||
|
||||
public function setLastName($lastName) {
|
||||
$this->lastName = $lastName;
|
||||
}
|
||||
|
||||
public function getLogin() {
|
||||
return $this->login;
|
||||
}
|
||||
|
||||
public function setLogin($login) {
|
||||
$this->login = $login;
|
||||
}
|
||||
|
||||
public function getPassword() {
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
public function setPassword($password) {
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
public function getRole() {
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
public function setRole($role) {
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
public function getLastLogin() {
|
||||
return $this->lastLogin;
|
||||
}
|
||||
|
||||
public function setLastLogin($lastLogin) {
|
||||
$this->lastLogin = $lastLogin;
|
||||
}
|
||||
|
||||
public function getOnline() {
|
||||
return $this->online;
|
||||
}
|
||||
|
||||
public function setOnline($online) {
|
||||
$this->online = $online;
|
||||
}
|
||||
|
||||
public function getLastActivity() {
|
||||
return $this->lastActivity;
|
||||
}
|
||||
|
||||
public function setLastActivity($lastActivity) {
|
||||
$this->lastActivity = $lastActivity;
|
||||
}
|
||||
|
||||
|
||||
public function getPhone() {
|
||||
return $this->phone;
|
||||
}
|
||||
|
||||
public function setPhone($phone) {
|
||||
$this->phone = $phone;
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription($description) {
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
public function getAuthorized() {
|
||||
return $this->authorized;
|
||||
}
|
||||
|
||||
public function setAuthorized($authorized) {
|
||||
$this->authorized = $authorized;
|
||||
}
|
||||
|
||||
public function getPhotoSrc() {
|
||||
return $this->photoSrc;
|
||||
}
|
||||
|
||||
public function setPhotoSrc($photoSrc) {
|
||||
$this->photoSrc = $photoSrc;
|
||||
}
|
||||
|
||||
public function getForumCount() {
|
||||
return $this->forumCount;
|
||||
}
|
||||
|
||||
public function setForumCount($forumCount) {
|
||||
$this->forumCount = $forumCount;
|
||||
}
|
||||
|
||||
public function GetPhotoUrl($type = 120) {
|
||||
if($this->photoSrc) {
|
||||
switch($type) {
|
||||
case 50:
|
||||
return $this->photoSrc .'_50.' . PhotoDAL::PHOTO_NEW_EXT;
|
||||
break;
|
||||
|
||||
case 120:
|
||||
return $this->photoSrc .'_120.' . PhotoDAL::PHOTO_NEW_EXT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return $this->photoSrc .'_120.'. PhotoDAL::PHOTO_NEW_EXT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Funkcja kontrolna
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function IsAuthorized() {
|
||||
return $this->authorized;
|
||||
}
|
||||
|
||||
|
||||
public function getAccess() {
|
||||
|
||||
if($this->access == null){
|
||||
$this->access = AdminDAL::GetArrayAccess($this);
|
||||
}
|
||||
return $this->access;
|
||||
}
|
||||
|
||||
public function setAccess($access) {
|
||||
$this->access = $access;
|
||||
}
|
||||
|
||||
public function getCreateTime() {
|
||||
return $this->createTime;
|
||||
}
|
||||
|
||||
public function setCreateTime($createTime) {
|
||||
$this->createTime = $createTime;
|
||||
}
|
||||
|
||||
public function getArchive() {
|
||||
return $this->archive;
|
||||
}
|
||||
|
||||
public function setArchive($archive) {
|
||||
$this->archive = $archive;
|
||||
}
|
||||
|
||||
public function getDeleteTime() {
|
||||
return $this->deleteTime;
|
||||
}
|
||||
|
||||
public function setDeleteTime($deleteTime) {
|
||||
$this->deleteTime = $deleteTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sprawdza uprawnienia do zasobu
|
||||
*
|
||||
* @param string $where
|
||||
* @return boolean
|
||||
*/
|
||||
public function CheckAccess($where) {
|
||||
|
||||
|
||||
if (array_key_exists($where, $this->access)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
320
Admin/module/AdminDAL.mod.php
Normal file
320
Admin/module/AdminDAL.mod.php
Normal file
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* $Id: AdminDAL.mod.php 773 2008-07-01 06:19:05Z dakl $
|
||||
* Klasa do obs<62>ugi odwo<77>a<EFBFBD> do bazy danych:
|
||||
* - pobieranie danych
|
||||
* - usuwanie
|
||||
* - dodawanie
|
||||
* - edycja
|
||||
* - modyfikacja has<61>a
|
||||
*
|
||||
*/
|
||||
class AdminDAL extends DefaultDAL {
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Ustawienia tabeli na której operuje DAL">
|
||||
protected static $objClassName;
|
||||
protected static $objClassTable;
|
||||
protected static $objClassTablePK;
|
||||
private static $optClass;
|
||||
|
||||
// </editor-fold>
|
||||
// <editor-fold defaultstate="collapsed" desc="Funkcje pobierające nazwy tabeli, klucza głównego, nazwy klasy na której operuje DAL">
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public static function GetObjClassName() {
|
||||
if (self::$objClassName != '') {
|
||||
$class = self::$objClassName;
|
||||
} else {
|
||||
$class = str_replace('DAL', '', __CLASS__);
|
||||
}
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public static function GetOptClass() {
|
||||
if (self::$optClass != null) {
|
||||
return self::$optClass;
|
||||
} else {
|
||||
return self::GetObjClassName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public static function GetObjClassTablePK() {
|
||||
if (self::$objClassTablePK != '') {
|
||||
$return = self::$objClassTablePK;
|
||||
} else {
|
||||
$class = self::GetObjClassName();
|
||||
$classObj = new $class();
|
||||
$return = $classObj->GetClassTablePK();
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public static function GetObjClassTable() {
|
||||
if (!is_null(self::$objClassTable)) {
|
||||
$return = self::$objClassTable;
|
||||
} else {
|
||||
$class = self::GetObjClassName();
|
||||
$classObj = new $class();
|
||||
$return = $classObj->GetTableName();
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
// <editor-fold defaultstate="collapsed" desc="Domyślne metody wymagane przez IDefaultDAL">
|
||||
|
||||
/**
|
||||
* @param User $obj
|
||||
*
|
||||
*/
|
||||
public static function Save($obj) {
|
||||
if ($obj->GetId() == -1) {
|
||||
return self::Insert($obj);
|
||||
} else {
|
||||
return self::Update($obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $obj
|
||||
*
|
||||
*/
|
||||
public static function Insert($obj) {
|
||||
$dalData = new DalData();
|
||||
$dalData->setObjClassTable(self::GetObjClassTable());
|
||||
$dalData->setObj($obj);
|
||||
return self::DefaultInsert($dalData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $obj
|
||||
*
|
||||
*/
|
||||
public static function Update($obj) {
|
||||
$dalData = new DalData();
|
||||
$dalData->setObjClassTable(self::GetObjClassTable());
|
||||
$dalData->setObjClassTablePK(self::GetObjClassTablePK());
|
||||
$dalData->setObj($obj);
|
||||
return self::DefaultUpdate($dalData);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param integer $id
|
||||
*
|
||||
*/
|
||||
public static function Delete($obj) {
|
||||
$dalData = new DalData();
|
||||
$dalData->setObjClassTable(self::GetObjClassTable());
|
||||
$dalData->setObjClassTablePK(self::GetObjClassTablePK());
|
||||
$dalData->setObj($obj);
|
||||
$dalData->setId($obj->GetId());
|
||||
return self::DefaultDelete($dalData);
|
||||
}
|
||||
|
||||
public static function GetDalDataObj() {
|
||||
$dalData = new DalData();
|
||||
$dalData->setObjClassName(self::GetObjClassName());
|
||||
$dalData->setObjClassTable(self::GetObjClassTable());
|
||||
$dalData->setObjClassTablePK(self::GetObjClassTablePK());
|
||||
$dalData->setOptClass(self::GetOptClass());
|
||||
return $dalData;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param integer $id
|
||||
* @return User
|
||||
*/
|
||||
public static function GetById($id) {
|
||||
$result = self::GetResult(array(self::GetObjClassTablePK() => $id), array(), 1);
|
||||
if (is_object($result[0])) {
|
||||
return $result[0];
|
||||
} else {
|
||||
throw new Exception('Brak rekordu w tablicy ' . self::GetObjClassTable() . ' o id <b>' . $id . '</b>!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pobiera liste rekordow
|
||||
* @param <array> $data - pola do where
|
||||
* @param <array> $queryFields - pobierane pola
|
||||
* @param <string> $limit - limit rekordow
|
||||
* @param <string> $sortBy - sortowanie
|
||||
* @param <bool> $count - czy ma zwracac ilosc rekordow
|
||||
* @return <array> - tablica obiektow lub jesli usawiony count liczba rekordow
|
||||
*/
|
||||
public static function GetResult($data = array(), $queryFields = array(), $limit = 0, $sortBy = null, $count = null) {
|
||||
$dalData = new DalData();
|
||||
$dalData->setObjClassName(self::GetObjClassName());
|
||||
$dalData->setObjClassTable(self::GetObjClassTable());
|
||||
$dalData->setObjClassTablePK(self::GetObjClassTablePK());
|
||||
$dalData->setOptClass(self::GetOptClass());
|
||||
$dalData->setCondition($data);
|
||||
$dalData->setQueryFields($queryFields);
|
||||
$dalData->setLimit($limit);
|
||||
$dalData->setSortBy($sortBy);
|
||||
$dalData->setCount($count);
|
||||
|
||||
return self::DefaultGetResult($dalData, false);
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
|
||||
public static function GetArrayAccess($obj) {
|
||||
|
||||
$db = Registry::Get('db');
|
||||
$sql = "SELECT access from mf_admin_access where role=:1";
|
||||
$stmt = $db->Prepare($sql)
|
||||
->BindParam(1, $obj->getRole())
|
||||
->Execute();
|
||||
|
||||
$access = array();
|
||||
while ($row = $stmt->FetchArray()) {
|
||||
$access[$row['access']] = true;
|
||||
}
|
||||
return $access;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pobieranie listy rol
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function GetArrayObjRoles() {
|
||||
|
||||
$db = Registry::Get('db');
|
||||
$sql = "SELECT DISTINCT role from mf_admin_access";
|
||||
$stmt = $db->execute($sql);
|
||||
return $stmt->FetchAllAssoc();
|
||||
}
|
||||
|
||||
public static function UpdateAvatar($id, $files) {
|
||||
$filename = PhotoDAL::SimplePhotoUpload($files, "avatar", 100, 100, 90, "_$id");
|
||||
$db = Registry::Get('db');
|
||||
$sql = "UPDATE " . self::GetObjClassTable() . " set avatar=:*#1#* WHERE " . self::GetObjClassTablePK() . "=:*#2#*";
|
||||
$stmt = $db->prepare($sql)
|
||||
->bindParam("*#1#*", $filename)
|
||||
->bindParam("*#2#*", $id)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zmiana hasla
|
||||
*
|
||||
* @param integer $id
|
||||
* @param string $password
|
||||
* @param string $oldPassword
|
||||
*/
|
||||
public static function UpdatePassword($id, $password, $oldPassword = null) {
|
||||
$db = Registry::Get('db');
|
||||
$sql = "UPDATE " . self::GetObjClassTable() . " set password=:1 WHERE " . self::GetObjClassTablePK() . "=:2";
|
||||
$stmt = $db->prepare($sql)
|
||||
->bindParam(1, $password)
|
||||
->bindParam(2, $id)
|
||||
->bindParam(3, $oldPassword)
|
||||
->execute();
|
||||
}
|
||||
|
||||
public static function CheckPassword($id, $password) {
|
||||
$db = Registry::Get('db');
|
||||
$sql = "select count(*) from " . self::GetObjClassTable() . " WHERE password=:1 AND " . self::GetObjClassTablePK() . "=:2";
|
||||
$stmt = $db->prepare($sql)
|
||||
->bindParam(1, $password)
|
||||
->bindParam(2, $id)
|
||||
->execute();
|
||||
|
||||
$result = $stmt->FetchRow();
|
||||
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
public static function DoActivity($obj) {
|
||||
$db = Registry::Get('db');
|
||||
$sql = "UPDATE " . self::GetObjClassTable() . " SET last_activity = NOW() WHERE " . self::GetObjClassTablePK() . "=:*#1#*";
|
||||
$stmt = $db->prepare($sql)
|
||||
->bindParam('*#1#*', $obj->GetId())
|
||||
->execute();
|
||||
|
||||
return $obj->GetId();
|
||||
}
|
||||
|
||||
public static function GetResultByLink($table, $id, $data = array(), $limit = 0, $sortBy = null, $count = null) {
|
||||
if (!is_array($data)) {
|
||||
$data = array();
|
||||
}
|
||||
|
||||
$db = Registry::Get('db');
|
||||
if ($count == true)
|
||||
$select = 'count(*) as count';
|
||||
else
|
||||
$select = " " . SQL::ToSelect('Admin') . " ";
|
||||
|
||||
$sql = " SELECT $select FROM " . self::GetObjClassTable() . " INNER JOIN mf_link ON " . self::GetObjClassTable() . "." . self::GetObjClassTablePK() . "=mf_link.id_destination WHERE mf_link.destination_type='" . self::GetObjClassTable() . "' AND mf_link.source_type='$table' AND mf_link.id_source=$id ";
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if ($key == "id")
|
||||
$key = 'id_mf_admin';
|
||||
|
||||
if (is_array($value))
|
||||
$sql .= ( is_numeric($value['value']) || $value ? " AND " . $key . " " . $value['condition'] . " " . $value['value'] : "");
|
||||
else
|
||||
$sql .= ( is_numeric($value) || $value ? " AND " . $key . " = " . $value : "");
|
||||
}
|
||||
$sql .= ( trim($sortBy) ? " ORDER BY $sortBy " : "") .
|
||||
( $limit ? " LIMIT " . $limit : "") .
|
||||
" ";
|
||||
$stmt = $db->prepare($sql)
|
||||
->execute();
|
||||
$array = $stmt->fetchAllAssoc();
|
||||
|
||||
if ($count == true)
|
||||
return $array[0]['count'];
|
||||
|
||||
$done = array();
|
||||
for ($i = 0; $i < count($array); $i++) {
|
||||
$obj = new Admin();
|
||||
$obj->FromArray($array[$i], 1);
|
||||
$done[$obj->GetId()] = $obj;
|
||||
}
|
||||
return $done;
|
||||
}
|
||||
|
||||
public static function GetLinkedProfiles($id, $limit) {
|
||||
return self::GetResult(array(self::GetObjClassTablePK() => array('condition' => '<>', 'value' => $id)), array(), $limit);
|
||||
}
|
||||
|
||||
public static function NewMessageNotify($userId, $subject = null, $sender = null, $smarty = null, $messageId = null) {
|
||||
$admin = new Admin();
|
||||
$admin = self::GetById($userId);
|
||||
// $physSet = new ProfileSettings();
|
||||
// $physSet = ProfileSettingsDAL::GetByAdminId($userId);
|
||||
// if($physSet -> GetNotifyNewMessage() == 1){
|
||||
$smarty->assign('msgId', $messageId);
|
||||
$smarty->assign('subject', $subject);
|
||||
$smarty->assign('sender', $sender);
|
||||
$mail = new Mailer();
|
||||
$mail->AddAddress($admin->GetEmail(), $admin->GetEmail());
|
||||
$mail->SendEmail($smarty->fetch('partial/Mail/Newmessage.tpl'), '', 'Nowa wiadomość w Twojej skrzynce odbiorczej');
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
106
Admin/module/AuthDAL.mod.php
Normal file
106
Admin/module/AuthDAL.mod.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?
|
||||
|
||||
/**
|
||||
* $Id: AuthDAL.mod.php 708 2008-06-26 13:48:43Z pawy $
|
||||
* Klasa autoryzacji usera
|
||||
*
|
||||
*/
|
||||
class AuthDAL {
|
||||
/**
|
||||
* Pusty konstruktor
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sprawdza uzytkownika i haslo, loguje usera , zapisuje obiekt klasy User do sesji i zwraca 1/0
|
||||
*
|
||||
* @param string $login
|
||||
* @param string $password
|
||||
* @return boolean
|
||||
*/
|
||||
public static function Login($login, $password) {
|
||||
|
||||
$adminList = AdminDAL::GetResult(array("login" => $login, "password" => md5(trim($password))), array(), 1);
|
||||
//Utils::ArrayDisplay($adminList);
|
||||
|
||||
if(!empty($adminList)) {
|
||||
|
||||
$admin = $adminList[0];
|
||||
$admin->SetAuthorized(true);
|
||||
$lastLogin = $admin->GetLastLogin();
|
||||
$admin->SetLastLogin('NOW()');
|
||||
|
||||
AdminDAL::Save($admin);
|
||||
|
||||
$admin->SetLastLogin($lastLogin);
|
||||
$admin->GetAccess();
|
||||
|
||||
SessionProxy::SetValue(EnumSessionValue::ADMIN_OBJECT, $admin);
|
||||
return $admin->GetId();
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zwraca obiekt klasy User lub 0
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function GetAdmin() {
|
||||
|
||||
$admin = SessionProxy::GetValue(EnumSessionValue::ADMIN_OBJECT);
|
||||
//Utils::ArrayDisplay($admin);
|
||||
$remember = Request::GetCookie('remember');
|
||||
if(is_object($admin) ){
|
||||
return $admin;
|
||||
} else if(isset($remember) && $remember == '1'){
|
||||
$adminList = AdminDAL::GetResult(array("hash" => Request::GetCookie('key')), array(), 1);
|
||||
|
||||
if(!empty($adminList)) {
|
||||
$admin = $adminList[0];
|
||||
|
||||
$admin->SetAuthorized(true);
|
||||
$admin->GetAccess();
|
||||
Registry::Set('admin', $admin);
|
||||
SessionProxy::SetValue(EnumSessionValue::ADMIN_OBJECT, $admin);
|
||||
return $admin;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Przeladowuje uzytkownika w sesji
|
||||
*
|
||||
* @param
|
||||
*/
|
||||
public static function ReloadUser() {
|
||||
$admin = SessionProxy::GetValue(EnumSessionValue::ADMIN_OBJECT);
|
||||
$adminId = $admin->GetId();
|
||||
|
||||
$admin = AdminDAL::GetById($adminId);
|
||||
$admin->GetAccess();
|
||||
|
||||
$admin->SetAuthorized(true);
|
||||
SessionProxy::ClearValue(EnumSessionValue::ADMIN_OBJECT);
|
||||
SessionProxy::SetValue(EnumSessionValue::ADMIN_OBJECT, $admin);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Czysci sesje wylogowujac usera
|
||||
*
|
||||
*/
|
||||
public static function Logout() {
|
||||
SessionProxy::ClearValue(EnumSessionValue::ADMIN_OBJECT);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
34
Admin/module/CacheParam.mod.php
Normal file
34
Admin/module/CacheParam.mod.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?
|
||||
|
||||
/**
|
||||
* $Id$
|
||||
* Paramerty chache dla poszczegolnych elementow
|
||||
*
|
||||
*/
|
||||
class CacheParam {
|
||||
/**
|
||||
* Globalny parametr uzywany wszedzie tam, gdzie nie jest zdefiniowane inaczej
|
||||
*
|
||||
* @var unknown_type
|
||||
*/
|
||||
public static $global = '30';
|
||||
|
||||
|
||||
/**
|
||||
* Metoda do pobierania konkretnego parametru
|
||||
*
|
||||
* @param string $param
|
||||
* @return int
|
||||
*/
|
||||
public static function Get($param) {
|
||||
if(isset(self::$$param)) {
|
||||
return self::$$param;
|
||||
}
|
||||
else {
|
||||
return self::$global;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
68
Admin/module/LightBBCodeParser.mod.php
Normal file
68
Admin/module/LightBBCodeParser.mod.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Class for parsing BBCode
|
||||
*
|
||||
* This class can be use for parsing common BBCode tags.
|
||||
*
|
||||
* @license GNU General Public License
|
||||
* @author Nikola Posa, www.nikolaposa.in.rs
|
||||
*/
|
||||
class LightBBCodeParser {
|
||||
|
||||
//array of bbcode patterns
|
||||
protected $patterns = array
|
||||
(
|
||||
'/\n/Ui',
|
||||
'/\[b\]/Ui',
|
||||
'/\[\/b\]/Ui',
|
||||
'/\[i\]/Ui',
|
||||
'/\[\/i\]/Ui',
|
||||
'/\[u\]/Ui',
|
||||
'/\[\/u\]/Ui',
|
||||
'/\[s\]/Ui',
|
||||
'/\[\/s\]/Ui',
|
||||
'/\[size=([0-9]+)\]/Ui',
|
||||
'/\[\/size\]/Ui',
|
||||
'/\[url=([^\]]+)\](.*?)\[\/url\]/Ui',
|
||||
'/\[url\](.*?)\[\/url\]/Ui',
|
||||
'/\[img\](.*?)\[\/img\]/Ui',
|
||||
'/\[color=([^\]]*?)\]([^\[]*?)\[\/color\]/Ui',
|
||||
'/\[code\](.*?)\[\/code\]/Ui',
|
||||
'/\[quote.*?\](.*?)\[\/quote\]/Ui'
|
||||
);
|
||||
|
||||
//array of HTML tags that correspond to bbcode patterns
|
||||
protected $replacements = array
|
||||
(
|
||||
'<br />',
|
||||
'<span class="bbcodeB">',
|
||||
'</span>',
|
||||
'<span class="bbcodeI">',
|
||||
'</span>',
|
||||
'<span class="bbcodeU">',
|
||||
'</span>',
|
||||
'<span class="bbcodeS">',
|
||||
'</span>',
|
||||
'<span style="font-size: \1px;">',
|
||||
'</span>',
|
||||
'<a href="\1">\2</a>',
|
||||
'<a href="\1">\1</a>',
|
||||
'<img src="\1" />',
|
||||
'<span style="color: \1">\2</span>',
|
||||
'<span class="bbcodeCode">\1</span>',
|
||||
'<span class="bbcodeQuote">\1</span>'
|
||||
);
|
||||
|
||||
/**
|
||||
* This function converts bbcode to (x)HTML tags.
|
||||
*
|
||||
* @param string Text that will be parsed.
|
||||
* @return string
|
||||
*/
|
||||
public function bbc2html($subject){
|
||||
$subject = preg_replace($this->patterns, $this->replacements, $subject);
|
||||
|
||||
return $subject;
|
||||
}
|
||||
}
|
||||
?>
|
||||
2339
Admin/plugins/ckeditor/CHANGES.md
Normal file
2339
Admin/plugins/ckeditor/CHANGES.md
Normal file
File diff suppressed because it is too large
Load Diff
1670
Admin/plugins/ckeditor/LICENSE.md
Normal file
1670
Admin/plugins/ckeditor/LICENSE.md
Normal file
File diff suppressed because it is too large
Load Diff
39
Admin/plugins/ckeditor/README.md
Normal file
39
Admin/plugins/ckeditor/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
CKEditor 4
|
||||
==========
|
||||
|
||||
Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
https://ckeditor.com - See https://ckeditor.com/legal/ckeditor-oss-license for license information.
|
||||
|
||||
CKEditor 4 is a text editor to be used inside web pages. It's not a replacement
|
||||
for desktop text editors like Word or OpenOffice, but a component to be used as
|
||||
part of web applications and websites.
|
||||
|
||||
## Documentation
|
||||
|
||||
The full editor documentation is available online at the following address:
|
||||
https://ckeditor.com/docs/
|
||||
|
||||
## Installation
|
||||
|
||||
Installing CKEditor is an easy task. Just follow these simple steps:
|
||||
|
||||
1. **Download** the latest version from the CKEditor website:
|
||||
https://ckeditor.com. You should have already completed this step, but be
|
||||
sure you have the very latest version.
|
||||
2. **Extract** (decompress) the downloaded file into the root of your website.
|
||||
|
||||
**Note:** CKEditor is by default installed in the `ckeditor` folder. You can
|
||||
place the files in whichever you want though.
|
||||
|
||||
## Checking Your Installation
|
||||
|
||||
The editor comes with a few sample pages that can be used to verify that
|
||||
installation proceeded properly. Take a look at the `samples` directory.
|
||||
|
||||
To test your installation, just call the following page at your website:
|
||||
|
||||
http://<your site>/<CKEditor installation path>/samples/index.html
|
||||
|
||||
For example:
|
||||
|
||||
http://www.example.com/ckeditor/samples/index.html
|
||||
10
Admin/plugins/ckeditor/SECURITY.md
Normal file
10
Admin/plugins/ckeditor/SECURITY.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Reporting a security issues
|
||||
|
||||
If you believe you have found a security issue in the CKEditor 4 software, please contact us immediately.
|
||||
|
||||
When reporting a potential security problem, please bear this in mind:
|
||||
|
||||
* Make sure to provide as many details as possible about the vulnerability.
|
||||
* Please do not disclose publicly any security issues until we fix them and publish security releases.
|
||||
|
||||
Contact the security team at security@cksource.com. As soon as we receive the security report, we will work promptly to confirm the issue and then to provide a security fix.
|
||||
379
Admin/plugins/ckeditor/adapters/jquery.js
vendored
Normal file
379
Admin/plugins/ckeditor/adapters/jquery.js
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR_Adapters.jQuery jQuery Adapter}.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class CKEDITOR_Adapters.jQuery
|
||||
* @singleton
|
||||
*
|
||||
* The jQuery Adapter allows for easy use of basic CKEditor functions and access to the internal API.
|
||||
* To find more information about the jQuery Adapter, go to the {@glink guide/dev_jquery jQuery Adapter section}
|
||||
* of the Developer's Guide or see the "Create Editors with jQuery" sample.
|
||||
*
|
||||
* @aside guide dev_jquery
|
||||
*/
|
||||
|
||||
( function( $ ) {
|
||||
if ( typeof $ == 'undefined' ) {
|
||||
throw new Error( 'jQuery should be loaded before CKEditor jQuery adapter.' );
|
||||
}
|
||||
|
||||
if ( typeof CKEDITOR == 'undefined' ) {
|
||||
throw new Error( 'CKEditor should be loaded before CKEditor jQuery adapter.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows CKEditor to override `jQuery.fn.val()`. When set to `true`, the `val()` function
|
||||
* used on textarea elements replaced with CKEditor uses the CKEditor API.
|
||||
*
|
||||
* This configuration option is global and is executed during the loading of the jQuery Adapter.
|
||||
* It cannot be customized across editor instances.
|
||||
*
|
||||
* Read more in the {@glink guide/dev_jquery documentation}.
|
||||
*
|
||||
* <script>
|
||||
* CKEDITOR.config.jqueryOverrideVal = true;
|
||||
* </script>
|
||||
*
|
||||
* <!-- Important: The jQuery Adapter is loaded *after* setting jqueryOverrideVal. -->
|
||||
* <script src="/ckeditor/adapters/jquery.js"></script>
|
||||
*
|
||||
* <script>
|
||||
* $( 'textarea' ).ckeditor();
|
||||
* // ...
|
||||
* $( 'textarea' ).val( 'New content' );
|
||||
* </script>
|
||||
*
|
||||
* @cfg {Boolean} [jqueryOverrideVal=true]
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
CKEDITOR.config.jqueryOverrideVal =
|
||||
typeof CKEDITOR.config.jqueryOverrideVal == 'undefined' ? true : CKEDITOR.config.jqueryOverrideVal;
|
||||
|
||||
// jQuery object methods.
|
||||
$.extend( $.fn, {
|
||||
/**
|
||||
* Returns an existing CKEditor instance for the first matched element.
|
||||
* Allows to easily use the internal API. Does not return a jQuery object.
|
||||
*
|
||||
* Raises an exception if the editor does not exist or is not ready yet.
|
||||
*
|
||||
* @returns CKEDITOR.editor
|
||||
* @deprecated Use {@link #editor editor property} instead.
|
||||
*/
|
||||
ckeditorGet: function() {
|
||||
var instance = this.eq( 0 ).data( 'ckeditorInstance' );
|
||||
|
||||
if ( !instance )
|
||||
throw 'CKEditor is not initialized yet, use ckeditor() with a callback.';
|
||||
|
||||
return instance;
|
||||
},
|
||||
|
||||
/**
|
||||
* A jQuery function which triggers the creation of CKEditor with `<textarea>` and
|
||||
* {@link CKEDITOR.dtd#$editable editable} elements.
|
||||
* Every `<textarea>` element will be converted to a classic (`iframe`-based) editor,
|
||||
* while any other supported element will be converted to an inline editor.
|
||||
* This method binds the callback to the `instanceReady` event of all instances.
|
||||
* If the editor has already been created, the callback is fired straightaway.
|
||||
* You can also create multiple editors at once by using `$( '.className' ).ckeditor();`.
|
||||
*
|
||||
* **Note**: jQuery chaining and mixed parameter order is allowed.
|
||||
*
|
||||
* @param {Function} callback
|
||||
* Function to be run on the editor instance. Callback takes the source element as a parameter.
|
||||
*
|
||||
* $( 'textarea' ).ckeditor( function( textarea ) {
|
||||
* // Callback function code.
|
||||
* } );
|
||||
*
|
||||
* @param {Object} config
|
||||
* Configuration options for new instance(s) if not already created.
|
||||
*
|
||||
* $( 'textarea' ).ckeditor( {
|
||||
* uiColor: '#9AB8F3'
|
||||
* } );
|
||||
*
|
||||
* @returns jQuery.fn
|
||||
*/
|
||||
ckeditor: function( callback, config ) {
|
||||
if ( !CKEDITOR.env.isCompatible )
|
||||
throw new Error( 'The environment is incompatible.' );
|
||||
|
||||
// Reverse the order of arguments if the first one isn't a function.
|
||||
if ( typeof callback !== 'function' ) {
|
||||
var tmp = config;
|
||||
config = callback;
|
||||
callback = tmp;
|
||||
}
|
||||
|
||||
// An array of instanceReady callback promises.
|
||||
var promises = [];
|
||||
|
||||
config = config || {};
|
||||
|
||||
// Iterate over the collection.
|
||||
this.each( function() {
|
||||
var $element = $( this ),
|
||||
editor = $element.data( 'ckeditorInstance' ),
|
||||
instanceLock = $element.data( '_ckeditorInstanceLock' ),
|
||||
element = this,
|
||||
dfd = new $.Deferred();
|
||||
|
||||
promises.push( dfd.promise() );
|
||||
|
||||
if ( editor && !instanceLock ) {
|
||||
if ( callback )
|
||||
callback.apply( editor, [ this ] );
|
||||
|
||||
dfd.resolve();
|
||||
} else if ( !instanceLock ) {
|
||||
// CREATE NEW INSTANCE
|
||||
|
||||
// Handle config.autoUpdateElement inside this plugin if desired.
|
||||
if ( config.autoUpdateElement || ( typeof config.autoUpdateElement == 'undefined' && CKEDITOR.config.autoUpdateElement ) ) {
|
||||
config.autoUpdateElementJquery = true;
|
||||
}
|
||||
|
||||
// Always disable config.autoUpdateElement.
|
||||
config.autoUpdateElement = false;
|
||||
$element.data( '_ckeditorInstanceLock', true );
|
||||
|
||||
// Set instance reference in element's data.
|
||||
if ( $( this ).is( 'textarea' ) )
|
||||
editor = CKEDITOR.replace( element, config );
|
||||
else
|
||||
editor = CKEDITOR.inline( element, config );
|
||||
|
||||
$element.data( 'ckeditorInstance', editor );
|
||||
|
||||
// Register callback.
|
||||
editor.on( 'instanceReady', function( evt ) {
|
||||
var editor = evt.editor;
|
||||
|
||||
setTimeout( function waitForEditor() {
|
||||
// Delay bit more if editor is still not ready.
|
||||
if ( !editor.element ) {
|
||||
setTimeout( waitForEditor, 100 );
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove this listener. Triggered when new instance is ready.
|
||||
evt.removeListener();
|
||||
|
||||
/**
|
||||
* Forwards the CKEditor {@link CKEDITOR.editor#event-dataReady dataReady event} as a jQuery event.
|
||||
*
|
||||
* @event dataReady
|
||||
* @param {CKEDITOR.editor} editor Editor instance.
|
||||
*/
|
||||
editor.on( 'dataReady', function() {
|
||||
$element.trigger( 'dataReady.ckeditor', [ editor ] );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Forwards the CKEditor {@link CKEDITOR.editor#event-setData setData event} as a jQuery event.
|
||||
*
|
||||
* @event setData
|
||||
* @param {CKEDITOR.editor} editor Editor instance.
|
||||
* @param data
|
||||
* @param {String} data.dataValue The data that will be used.
|
||||
*/
|
||||
editor.on( 'setData', function( evt ) {
|
||||
$element.trigger( 'setData.ckeditor', [ editor, evt.data ] );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Forwards the CKEditor {@link CKEDITOR.editor#event-getData getData event} as a jQuery event.
|
||||
*
|
||||
* @event getData
|
||||
* @param {CKEDITOR.editor} editor Editor instance.
|
||||
* @param data
|
||||
* @param {String} data.dataValue The data that will be returned.
|
||||
*/
|
||||
editor.on( 'getData', function( evt ) {
|
||||
$element.trigger( 'getData.ckeditor', [ editor, evt.data ] );
|
||||
}, 999 );
|
||||
|
||||
/**
|
||||
* Forwards the CKEditor {@link CKEDITOR.editor#event-destroy destroy event} as a jQuery event.
|
||||
*
|
||||
* @event destroy
|
||||
* @param {CKEDITOR.editor} editor Editor instance.
|
||||
*/
|
||||
editor.on( 'destroy', function() {
|
||||
$element.trigger( 'destroy.ckeditor', [ editor ] );
|
||||
} );
|
||||
|
||||
// Overwrite save button to call jQuery submit instead of javascript submit.
|
||||
// Otherwise jQuery.forms does not work properly
|
||||
editor.on( 'save', function() {
|
||||
$( element.form ).trigger('submit');
|
||||
return false;
|
||||
}, null, null, 20 );
|
||||
|
||||
// Integrate with form submit.
|
||||
if ( editor.config.autoUpdateElementJquery && $element.is( 'textarea' ) && $( element.form ).length ) {
|
||||
var onSubmit = function() {
|
||||
$element.ckeditor( function() {
|
||||
editor.updateElement();
|
||||
} );
|
||||
};
|
||||
|
||||
// Bind to submit event.
|
||||
$( element.form ).on( 'submit', onSubmit );
|
||||
|
||||
// Bind to form-pre-serialize from jQuery Forms plugin.
|
||||
$( element.form ).on( 'form-pre-serialize', onSubmit );
|
||||
|
||||
// Unbind when editor destroyed.
|
||||
$element.on( 'destroy.ckeditor', function() {
|
||||
$( element.form ).off( 'submit', onSubmit );
|
||||
$( element.form ).off( 'form-pre-serialize', onSubmit );
|
||||
} );
|
||||
}
|
||||
|
||||
// Garbage collect on destroy.
|
||||
editor.on( 'destroy', function() {
|
||||
$element.removeData( 'ckeditorInstance' );
|
||||
} );
|
||||
|
||||
// Remove lock.
|
||||
$element.removeData( '_ckeditorInstanceLock' );
|
||||
|
||||
/**
|
||||
* Forwards the CKEditor {@link CKEDITOR.editor#event-instanceReady instanceReady event} as a jQuery event.
|
||||
*
|
||||
* @event instanceReady
|
||||
* @param {CKEDITOR.editor} editor Editor instance.
|
||||
*/
|
||||
$element.trigger( 'instanceReady.ckeditor', [ editor ] );
|
||||
|
||||
// Run given (first) code.
|
||||
if ( callback )
|
||||
callback.apply( editor, [ element ] );
|
||||
|
||||
dfd.resolve();
|
||||
}, 0 );
|
||||
}, null, null, 9999 );
|
||||
} else {
|
||||
// Editor is already during creation process, bind our code to the event.
|
||||
editor.once( 'instanceReady', function() {
|
||||
setTimeout( function waitForEditor() {
|
||||
// Delay bit more if editor is still not ready.
|
||||
if ( !editor.element ) {
|
||||
setTimeout( waitForEditor, 100 );
|
||||
return;
|
||||
}
|
||||
|
||||
// Run given code.
|
||||
if ( editor.element.$ == element && callback )
|
||||
callback.apply( editor, [ element ] );
|
||||
|
||||
dfd.resolve();
|
||||
}, 0 );
|
||||
}, null, null, 9999 );
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* The [jQuery Promise object](http://api.jquery.com/promise/) that handles the asynchronous constructor.
|
||||
* This promise will be resolved after **all** of the constructors.
|
||||
*
|
||||
* @property {Function} promise
|
||||
*/
|
||||
var dfd = new $.Deferred();
|
||||
|
||||
this.promise = dfd.promise();
|
||||
|
||||
$.when.apply( this, promises ).then( function() {
|
||||
dfd.resolve();
|
||||
} );
|
||||
|
||||
/**
|
||||
* Existing CKEditor instance. Allows to easily use the internal API.
|
||||
*
|
||||
* **Note**: This is not a jQuery object.
|
||||
*
|
||||
* var editor = $( 'textarea' ).ckeditor().editor;
|
||||
*
|
||||
* @property {CKEDITOR.editor} editor
|
||||
*/
|
||||
this.editor = this.eq( 0 ).data( 'ckeditorInstance' );
|
||||
|
||||
return this;
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* Overwritten jQuery `val()` method for `<textarea>` elements that have bound CKEditor instances.
|
||||
* This method gets or sets editor content by using the {@link CKEDITOR.editor#method-getData editor.getData()}
|
||||
* or {@link CKEDITOR.editor#method-setData editor.setData()} methods. To handle
|
||||
* the {@link CKEDITOR.editor#method-setData editor.setData()} callback (as `setData` is asynchronous),
|
||||
* `val( 'some data' )` will return a [jQuery Promise object](http://api.jquery.com/promise/).
|
||||
*
|
||||
* @method val
|
||||
* @returns String|Number|Array|jQuery.fn|function(jQuery Promise)
|
||||
*/
|
||||
if ( CKEDITOR.config.jqueryOverrideVal ) {
|
||||
$.fn.val = CKEDITOR.tools.override( $.fn.val, function( oldValMethod ) {
|
||||
return function( value ) {
|
||||
// Setter, i.e. .val( "some data" );
|
||||
if ( arguments.length ) {
|
||||
var _this = this,
|
||||
promises = [], //use promise to handle setData callback
|
||||
|
||||
result = this.each( function() {
|
||||
var $elem = $( this ),
|
||||
editor = $elem.data( 'ckeditorInstance' );
|
||||
|
||||
// Handle .val for CKEditor.
|
||||
if ( $elem.is( 'textarea' ) && editor ) {
|
||||
var dfd = new $.Deferred();
|
||||
|
||||
editor.setData( value, function() {
|
||||
dfd.resolve();
|
||||
} );
|
||||
|
||||
promises.push( dfd.promise() );
|
||||
return true;
|
||||
// Call default .val function for rest of elements
|
||||
} else {
|
||||
return oldValMethod.call( $elem, value );
|
||||
}
|
||||
} );
|
||||
|
||||
// If there is no promise return default result (jQuery object of chaining).
|
||||
if ( !promises.length )
|
||||
return result;
|
||||
// Create one promise which will be resolved when all of promises will be done.
|
||||
else {
|
||||
var dfd = new $.Deferred();
|
||||
|
||||
$.when.apply( this, promises ).done( function() {
|
||||
dfd.resolveWith( _this );
|
||||
} );
|
||||
|
||||
return dfd.promise();
|
||||
}
|
||||
}
|
||||
// Getter .val();
|
||||
else {
|
||||
var $elem = $( this ).eq( 0 ),
|
||||
editor = $elem.data( 'ckeditorInstance' );
|
||||
|
||||
if ( $elem.is( 'textarea' ) && editor )
|
||||
return editor.getData();
|
||||
else
|
||||
return oldValMethod.call( $elem );
|
||||
}
|
||||
};
|
||||
} );
|
||||
}
|
||||
} )( window.jQuery );
|
||||
16
Admin/plugins/ckeditor/bender-runner.config.json
Normal file
16
Admin/plugins/ckeditor/bender-runner.config.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"bender": {
|
||||
"port": 9001
|
||||
},
|
||||
"server": {
|
||||
"port": 9002
|
||||
},
|
||||
"paths": {
|
||||
"ckeditor4": "../ckeditor4/",
|
||||
"runner": "./src/runner.html"
|
||||
},
|
||||
"browsers": {
|
||||
"linux": [ "chrome", "firefox" ],
|
||||
"macos": [ "safari" ]
|
||||
}
|
||||
}
|
||||
126
Admin/plugins/ckeditor/build-config.js
Normal file
126
Admin/plugins/ckeditor/build-config.js
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file was added automatically by CKEditor builder.
|
||||
* You may re-use it at any time to build CKEditor again.
|
||||
*
|
||||
* If you would like to build CKEditor online again
|
||||
* (for example to upgrade), visit one the following links:
|
||||
*
|
||||
* (1) https://ckeditor.com/cke4/builder
|
||||
* Visit online builder to build CKEditor from scratch.
|
||||
*
|
||||
* (2) https://ckeditor.com/cke4/builder/6efec1cd51a3e9e0748902688573526a
|
||||
* Visit online builder to build CKEditor, starting with the same setup as before.
|
||||
*
|
||||
* (3) https://ckeditor.com/cke4/builder/download/6efec1cd51a3e9e0748902688573526a
|
||||
* Straight download link to the latest version of CKEditor (Optimized) with the same setup as before.
|
||||
*
|
||||
* NOTE:
|
||||
* This file is not used by CKEditor, you may remove it.
|
||||
* Changing this file will not change your CKEditor configuration.
|
||||
*/
|
||||
|
||||
var CKBUILDER_CONFIG = {
|
||||
skin: 'office2013',
|
||||
preset: 'full',
|
||||
ignore: [
|
||||
'.DS_Store',
|
||||
'.bender',
|
||||
'.editorconfig',
|
||||
'.gitattributes',
|
||||
'.gitignore',
|
||||
'.idea',
|
||||
'.jscsrc',
|
||||
'.jshintignore',
|
||||
'.jshintrc',
|
||||
'.mailmap',
|
||||
'.npm',
|
||||
'.nvmrc',
|
||||
'.travis.yml',
|
||||
'bender-err.log',
|
||||
'bender-out.log',
|
||||
'bender.ci.js',
|
||||
'bender.js',
|
||||
'dev',
|
||||
'gruntfile.js',
|
||||
'less',
|
||||
'node_modules',
|
||||
'package-lock.json',
|
||||
'package.json',
|
||||
'tests'
|
||||
],
|
||||
plugins : {
|
||||
'a11yhelp' : 1,
|
||||
'about' : 1,
|
||||
'basicstyles' : 1,
|
||||
'bidi' : 1,
|
||||
'blockquote' : 1,
|
||||
'clipboard' : 1,
|
||||
'colorbutton' : 1,
|
||||
'colordialog' : 1,
|
||||
'contextmenu' : 1,
|
||||
'copyformatting' : 1,
|
||||
'dialogadvtab' : 1,
|
||||
'div' : 1,
|
||||
'editorplaceholder' : 1,
|
||||
'elementspath' : 1,
|
||||
'enterkey' : 1,
|
||||
'entities' : 1,
|
||||
'exportpdf' : 1,
|
||||
'filebrowser' : 1,
|
||||
'find' : 1,
|
||||
'floatingspace' : 1,
|
||||
'font' : 1,
|
||||
'format' : 1,
|
||||
'forms' : 1,
|
||||
'horizontalrule' : 1,
|
||||
'htmlwriter' : 1,
|
||||
'iframe' : 1,
|
||||
'image' : 1,
|
||||
'indentblock' : 1,
|
||||
'indentlist' : 1,
|
||||
'justify' : 1,
|
||||
'language' : 1,
|
||||
'link' : 1,
|
||||
'list' : 1,
|
||||
'liststyle' : 1,
|
||||
'magicline' : 1,
|
||||
'maximize' : 1,
|
||||
'newpage' : 1,
|
||||
'pagebreak' : 1,
|
||||
'pastefromgdocs' : 1,
|
||||
'pastefromlibreoffice' : 1,
|
||||
'pastefromword' : 1,
|
||||
'pastetext' : 1,
|
||||
'preview' : 1,
|
||||
'print' : 1,
|
||||
'removeformat' : 1,
|
||||
'resize' : 1,
|
||||
'save' : 1,
|
||||
'scayt' : 1,
|
||||
'selectall' : 1,
|
||||
'showblocks' : 1,
|
||||
'showborders' : 1,
|
||||
'smiley' : 1,
|
||||
'sourcearea' : 1,
|
||||
'specialchar' : 1,
|
||||
'stylescombo' : 1,
|
||||
'tab' : 1,
|
||||
'table' : 1,
|
||||
'tableselection' : 1,
|
||||
'tabletools' : 1,
|
||||
'templates' : 1,
|
||||
'toolbar' : 1,
|
||||
'undo' : 1,
|
||||
'uploadimage' : 1,
|
||||
'wysiwygarea' : 1
|
||||
},
|
||||
languages : {
|
||||
'en' : 1,
|
||||
'pl' : 1
|
||||
}
|
||||
};
|
||||
47
Admin/plugins/ckeditor/ckeditor.js
vendored
Normal file
47
Admin/plugins/ckeditor/ckeditor.js
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
// Compressed version of core/ckeditor_base.js. See original for instructions.
|
||||
/* jshint ignore:start */
|
||||
/* jscs:disable */
|
||||
// replace_start
|
||||
window.CKEDITOR||(window.CKEDITOR=function(){var o,d=/(^|.*[\\\/])ckeditor\.js(?:\?.*|;.*)?$/i,e={timestamp:"",version:"%VERSION%",revision:"%REV%",rnd:Math.floor(900*Math.random())+100,_:{pending:[],basePathSrcPattern:d},status:"unloaded",basePath:function(){var t=window.CKEDITOR_BASEPATH||"";if(!t)for(var e=document.getElementsByTagName("script"),n=0;n<e.length;n++){var a=e[n].src.match(d);if(a){t=a[1];break}}if(-1==t.indexOf(":/")&&"//"!=t.slice(0,2)&&(t=0===t.indexOf("/")?location.href.match(/^.*?:\/\/[^\/]*/)[0]+t:location.href.match(/^[^\?]*\/(?:)/)[0]+t),!t)throw'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';return t}(),getUrl:function(t){return-1==t.indexOf(":/")&&0!==t.indexOf("/")&&(t=this.basePath+t),t=this.appendTimestamp(t)},appendTimestamp:function(t){if(!this.timestamp||"/"===t.charAt(t.length-1)||/[&?]t=/.test(t))return t;var e=0<=t.indexOf("?")?"&":"?";return t+e+"t="+this.timestamp},domReady:(o=[],function(t){if(o.push(t),"complete"===document.readyState&&setTimeout(i,1),1==o.length)if(document.addEventListener)document.addEventListener("DOMContentLoaded",i,!1),window.addEventListener("load",i,!1);else if(document.attachEvent){document.attachEvent("onreadystatechange",i),window.attachEvent("onload",i);var e=!1;try{e=!window.frameElement}catch(n){}document.documentElement.doScroll&&e&&!function a(){try{document.documentElement.doScroll("left")}catch(n){return void setTimeout(a,1)}i()}()}})};function i(){try{document.addEventListener?(document.removeEventListener("DOMContentLoaded",i,!1),window.removeEventListener("load",i,!1),n()):document.attachEvent&&"complete"===document.readyState&&(document.detachEvent("onreadystatechange",i),window.detachEvent("onload",i),n())}catch(t){}}function n(){for(var t;t=o.shift();)t()}var a,r=window.CKEDITOR_GETURL;return r&&(a=e.getUrl,e.getUrl=function(t){return r.call(e,t)||a.call(e,t)}),e}());
|
||||
// replace_end
|
||||
/* jscs:enable */
|
||||
/* jshint ignore:end */
|
||||
|
||||
if ( CKEDITOR.loader )
|
||||
CKEDITOR.loader.load( 'ckeditor' );
|
||||
else {
|
||||
// Set the script name to be loaded by the loader.
|
||||
CKEDITOR._autoLoad = 'ckeditor';
|
||||
|
||||
// Include the loader script.
|
||||
if ( document.body && ( !document.readyState || document.readyState == 'complete' ) ) {
|
||||
var script = document.createElement( 'script' );
|
||||
script.type = 'text/javascript';
|
||||
script.src = CKEDITOR.getUrl( 'core/loader.js' );
|
||||
document.body.appendChild( script );
|
||||
} else {
|
||||
document.write( '<script type="text/javascript" src="' + CKEDITOR.getUrl( 'core/loader.js' ) + '"></script>' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The skin to load for all created instances, it may be the name of the skin
|
||||
* folder inside the editor installation path, or the name and the path separated
|
||||
* by a comma.
|
||||
*
|
||||
* **Note:** This is a global configuration that applies to all instances.
|
||||
*
|
||||
* CKEDITOR.skinName = 'moono';
|
||||
*
|
||||
* CKEDITOR.skinName = 'myskin,/customstuff/myskin/';
|
||||
*
|
||||
* @cfg {String} [skinName='moono-lisa']
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.skinName = 'moono-lisa';
|
||||
45
Admin/plugins/ckeditor/config.js
Normal file
45
Admin/plugins/ckeditor/config.js
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
CKEDITOR.editorConfig = function( config ) {
|
||||
|
||||
// %REMOVE_START%
|
||||
// The configuration options below are needed when running CKEditor from source files.
|
||||
config.plugins = 'dialogui,dialog,about,a11yhelp,dialogadvtab,basicstyles,bidi,blockquote,notification,button,toolbar,clipboard,panelbutton,panel,floatpanel,colorbutton,colordialog,xml,ajax,templates,menu,contextmenu,copyformatting,div,editorplaceholder,resize,elementspath,enterkey,entities,exportpdf,popup,filetools,filebrowser,find,floatingspace,listblock,richcombo,font,fakeobjects,forms,format,horizontalrule,htmlwriter,iframe,wysiwygarea,image,indent,indentblock,indentlist,smiley,justify,menubutton,language,link,list,liststyle,magicline,maximize,newpage,pagebreak,pastetext,pastetools,pastefromgdocs,pastefromlibreoffice,pastefromword,preview,print,removeformat,save,selectall,showblocks,showborders,sourcearea,specialchar,scayt,stylescombo,tab,table,tabletools,tableselection,undo,lineutils,widgetselection,widget,notificationaggregator,uploadwidget,uploadimage';
|
||||
config.skin = 'office2013';
|
||||
// %REMOVE_END%
|
||||
|
||||
// Define changes to default configuration here. For example:
|
||||
// config.language = 'fr';
|
||||
config.uiColor = '#AADC6E';
|
||||
config.iframe_attributes = [
|
||||
{sandbox: 'allow-scripts allow-same-origin'},
|
||||
{allow: 'autoplay'}
|
||||
];
|
||||
|
||||
config.toolbarGroups = [
|
||||
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
|
||||
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] },
|
||||
{ name: 'forms', groups: [ 'forms' ] },
|
||||
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
|
||||
{ name: 'styles', groups: [ 'styles' ] },
|
||||
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi', 'paragraph' ] },
|
||||
'/',
|
||||
{ name: 'links', groups: [ 'links' ] },
|
||||
{ name: 'insert', groups: [ 'insert' ] },
|
||||
{ name: 'colors', groups: [ 'colors' ] },
|
||||
{ name: 'tools', groups: [ 'tools' ] },
|
||||
{ name: 'others', groups: [ 'others' ] },
|
||||
{ name: 'about', groups: [ 'about' ] },
|
||||
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
|
||||
'/'
|
||||
];
|
||||
|
||||
config.removeButtons = 'NewPage,ExportPdf,Preview,Print,Save,Templates,PasteFromWord,Find,SelectAll,Scayt,Replace,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,Language,Smiley,Styles';
|
||||
|
||||
//config.extraPlugins = 'pastecode';
|
||||
//config.removePlugins = 'link';
|
||||
//config.extraPlugins = 'adv_link';
|
||||
};
|
||||
208
Admin/plugins/ckeditor/contents.css
Normal file
208
Admin/plugins/ckeditor/contents.css
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
body
|
||||
{
|
||||
/* Font */
|
||||
/* Emoji fonts are added to visualise them nicely in Internet Explorer. */
|
||||
font-family: sans-serif, Arial, Verdana, "Trebuchet MS", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
font-size: 12px;
|
||||
|
||||
/* Text color */
|
||||
color: #333;
|
||||
|
||||
/* Remove the background color to make it transparent. */
|
||||
background-color: #fff;
|
||||
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.cke_editable
|
||||
{
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
|
||||
/* Fix for missing scrollbars with RTL texts. (#10488) */
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
blockquote
|
||||
{
|
||||
font-style: italic;
|
||||
font-family: Georgia, Times, "Times New Roman", serif;
|
||||
padding: 2px 0;
|
||||
border-style: solid;
|
||||
border-color: #ccc;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.cke_contents_ltr blockquote
|
||||
{
|
||||
padding-left: 20px;
|
||||
padding-right: 8px;
|
||||
border-left-width: 5px;
|
||||
}
|
||||
|
||||
.cke_contents_rtl blockquote
|
||||
{
|
||||
padding-left: 8px;
|
||||
padding-right: 20px;
|
||||
border-right-width: 5px;
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
color: #0782C1;
|
||||
}
|
||||
|
||||
ol,ul,dl
|
||||
{
|
||||
/* IE7: reset rtl list margin. (#7334) */
|
||||
*margin-right: 0px;
|
||||
/* Preserved spaces for list items with text direction different than the list. (#6249,#8049)*/
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6
|
||||
{
|
||||
font-weight: normal;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
hr
|
||||
{
|
||||
border: 0px;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
img.right
|
||||
{
|
||||
border: 1px solid #ccc;
|
||||
float: right;
|
||||
margin-left: 15px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
img.left
|
||||
{
|
||||
border: 1px solid #ccc;
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
pre
|
||||
{
|
||||
white-space: pre-wrap; /* CSS 2.1 */
|
||||
word-wrap: break-word; /* IE7 */
|
||||
-moz-tab-size: 4;
|
||||
tab-size: 4;
|
||||
}
|
||||
|
||||
.marker
|
||||
{
|
||||
background-color: Yellow;
|
||||
}
|
||||
|
||||
span[lang]
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
figure
|
||||
{
|
||||
text-align: center;
|
||||
outline: solid 1px #ccc;
|
||||
background: rgba(0,0,0,0.05);
|
||||
padding: 10px;
|
||||
margin: 10px 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
figure > figcaption
|
||||
{
|
||||
text-align: center;
|
||||
display: block; /* For IE8 */
|
||||
}
|
||||
|
||||
a > img {
|
||||
padding: 1px;
|
||||
margin: 1px;
|
||||
border: none;
|
||||
outline: 1px solid #0782C1;
|
||||
}
|
||||
|
||||
/* Widget Styles */
|
||||
.code-featured
|
||||
{
|
||||
border: 5px solid red;
|
||||
}
|
||||
|
||||
.math-featured
|
||||
{
|
||||
padding: 20px;
|
||||
box-shadow: 0 0 2px rgba(200, 0, 0, 1);
|
||||
background-color: rgba(255, 0, 0, 0.05);
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.image-clean
|
||||
{
|
||||
border: 0;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.image-clean > figcaption
|
||||
{
|
||||
font-size: .9em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.image-grayscale
|
||||
{
|
||||
background-color: white;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.image-grayscale img, img.image-grayscale
|
||||
{
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
.embed-240p
|
||||
{
|
||||
max-width: 426px;
|
||||
max-height: 240px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.embed-360p
|
||||
{
|
||||
max-width: 640px;
|
||||
max-height: 360px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.embed-480p
|
||||
{
|
||||
max-width: 854px;
|
||||
max-height: 480px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.embed-720p
|
||||
{
|
||||
max-width: 1280px;
|
||||
max-height: 720px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.embed-1080p
|
||||
{
|
||||
max-width: 1920px;
|
||||
max-height: 1080px;
|
||||
margin:0 auto;
|
||||
}
|
||||
69
Admin/plugins/ckeditor/core/_bootstrap.js
Normal file
69
Admin/plugins/ckeditor/core/_bootstrap.js
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview API initialization code.
|
||||
*/
|
||||
|
||||
( function() {
|
||||
// Check whether high contrast is active by creating a colored border.
|
||||
var hcDetect = CKEDITOR.dom.element.createFromHtml( '<div style="width:0;height:0;position:absolute;left:-10000px;' +
|
||||
'border:1px solid;border-color:red blue"></div>', CKEDITOR.document );
|
||||
|
||||
hcDetect.appendTo( CKEDITOR.document.getHead() );
|
||||
|
||||
// Update CKEDITOR.env.
|
||||
// Catch exception needed sometimes for FF. (https://dev.ckeditor.com/ticket/4230)
|
||||
try {
|
||||
var top = hcDetect.getComputedStyle( 'border-top-color' ),
|
||||
right = hcDetect.getComputedStyle( 'border-right-color' );
|
||||
|
||||
// We need to check if getComputedStyle returned any value, because on FF
|
||||
// it returnes empty string if CKEditor is loaded in hidden iframe. (https://dev.ckeditor.com/ticket/11121)
|
||||
CKEDITOR.env.hc = !!( top && top == right );
|
||||
} catch ( e ) {
|
||||
CKEDITOR.env.hc = false;
|
||||
}
|
||||
|
||||
hcDetect.remove();
|
||||
|
||||
if ( CKEDITOR.env.hc )
|
||||
CKEDITOR.env.cssClass += ' cke_hc';
|
||||
|
||||
// Initially hide UI spaces when relevant skins are loading, later restored by skin css.
|
||||
CKEDITOR.document.appendStyleText( '.cke{visibility:hidden;}' );
|
||||
|
||||
// Mark the editor as fully loaded.
|
||||
CKEDITOR.status = 'loaded';
|
||||
CKEDITOR.fireOnce( 'loaded' );
|
||||
|
||||
// Process all instances created by the "basic" implementation.
|
||||
var pending = CKEDITOR._.pending;
|
||||
if ( pending ) {
|
||||
delete CKEDITOR._.pending;
|
||||
|
||||
for ( var i = 0; i < pending.length; i++ ) {
|
||||
CKEDITOR.editor.prototype.constructor.apply( pending[ i ][ 0 ], pending[ i ][ 1 ] );
|
||||
CKEDITOR.add( pending[ i ][ 0 ] );
|
||||
}
|
||||
}
|
||||
} )();
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running on a High Contrast environment.
|
||||
*
|
||||
* if ( CKEDITOR.env.hc )
|
||||
* alert( 'You\'re running on High Contrast mode. The editor interface will get adapted to provide you a better experience.' );
|
||||
*
|
||||
* @property {Boolean} hc
|
||||
* @member CKEDITOR.env
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when a CKEDITOR core object is fully loaded and ready for interaction.
|
||||
*
|
||||
* @event loaded
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
209
Admin/plugins/ckeditor/core/ckeditor.js
vendored
Normal file
209
Admin/plugins/ckeditor/core/ckeditor.js
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Contains the third and last part of the {@link CKEDITOR} object
|
||||
* definition.
|
||||
*/
|
||||
|
||||
/** @class CKEDITOR */
|
||||
|
||||
// Remove the CKEDITOR.loadFullCore reference defined on ckeditor_basic.
|
||||
delete CKEDITOR.loadFullCore;
|
||||
|
||||
/**
|
||||
* Stores references to all editor instances created. The name of the properties
|
||||
* in this object correspond to instance names, and their values contain the
|
||||
* {@link CKEDITOR.editor} object representing them.
|
||||
*
|
||||
* alert( CKEDITOR.instances.editor1.name ); // 'editor1'
|
||||
*
|
||||
* @property {Object}
|
||||
*/
|
||||
CKEDITOR.instances = {};
|
||||
|
||||
/**
|
||||
* The document of the window storing the CKEDITOR object.
|
||||
*
|
||||
* alert( CKEDITOR.document.getBody().getName() ); // 'body'
|
||||
*
|
||||
* @property {CKEDITOR.dom.document}
|
||||
*/
|
||||
CKEDITOR.document = new CKEDITOR.dom.document( document );
|
||||
|
||||
/**
|
||||
* Adds an editor instance to the global {@link CKEDITOR} object. This function
|
||||
* is available for internal use mainly.
|
||||
*
|
||||
* @param {CKEDITOR.editor} editor The editor instance to be added.
|
||||
*/
|
||||
CKEDITOR.add = function( editor ) {
|
||||
CKEDITOR.instances[ editor.name ] = editor;
|
||||
|
||||
editor.on( 'focus', function() {
|
||||
if ( CKEDITOR.currentInstance != editor ) {
|
||||
CKEDITOR.currentInstance = editor;
|
||||
CKEDITOR.fire( 'currentInstance' );
|
||||
}
|
||||
} );
|
||||
|
||||
editor.on( 'blur', removeInstance );
|
||||
|
||||
// Remove currentInstance if it's destroyed (#589).
|
||||
editor.on( 'destroy', removeInstance );
|
||||
|
||||
CKEDITOR.fire( 'instance', null, editor );
|
||||
|
||||
function removeInstance() {
|
||||
if ( CKEDITOR.currentInstance == editor ) {
|
||||
CKEDITOR.currentInstance = null;
|
||||
CKEDITOR.fire( 'currentInstance' );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes an editor instance from the global {@link CKEDITOR} object. This function
|
||||
* is available for internal use only. External code must use {@link CKEDITOR.editor#method-destroy}.
|
||||
*
|
||||
* @private
|
||||
* @param {CKEDITOR.editor} editor The editor instance to be removed.
|
||||
*/
|
||||
CKEDITOR.remove = function( editor ) {
|
||||
delete CKEDITOR.instances[ editor.name ];
|
||||
};
|
||||
|
||||
( function() {
|
||||
var tpls = {};
|
||||
|
||||
/**
|
||||
* Adds a named {@link CKEDITOR.template} instance to be reused among all editors.
|
||||
* This will return the existing one if a template with same name is already
|
||||
* defined. Additionally, it fires the "template" event to allow template source customization.
|
||||
*
|
||||
* @param {String} name The name which identifies a UI template.
|
||||
* @param {String} source The source string for constructing this template.
|
||||
* @returns {CKEDITOR.template} The created template instance.
|
||||
*/
|
||||
CKEDITOR.addTemplate = function( name, source ) {
|
||||
var tpl = tpls[ name ];
|
||||
if ( tpl )
|
||||
return tpl;
|
||||
|
||||
// Make it possible to customize the template through event.
|
||||
var params = { name: name, source: source };
|
||||
CKEDITOR.fire( 'template', params );
|
||||
|
||||
return ( tpls[ name ] = new CKEDITOR.template( params.source ) );
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves a defined template created with {@link CKEDITOR#addTemplate}.
|
||||
*
|
||||
* @param {String} name The template name.
|
||||
*/
|
||||
CKEDITOR.getTemplate = function( name ) {
|
||||
return tpls[ name ];
|
||||
};
|
||||
} )();
|
||||
|
||||
( function() {
|
||||
var styles = [];
|
||||
|
||||
/**
|
||||
* Adds CSS rules to be appended to the editor document.
|
||||
* This method is mostly used by plugins to add custom styles to the editor
|
||||
* document. For basic content styling the `contents.css` file should be
|
||||
* used instead.
|
||||
*
|
||||
* **Note:** This function should be called before the creation of editor instances.
|
||||
*
|
||||
* // Add styles for all headings inside editable contents.
|
||||
* CKEDITOR.addCss( '.cke_editable h1,.cke_editable h2,.cke_editable h3 { border-bottom: 1px dotted red }' );
|
||||
*
|
||||
* @param {String} css The style rules to be appended.
|
||||
* @see CKEDITOR.config#contentsCss
|
||||
*/
|
||||
CKEDITOR.addCss = function( css ) {
|
||||
styles.push( css );
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a string with all CSS rules passed to the {@link CKEDITOR#addCss} method.
|
||||
*
|
||||
* @returns {String} A string containing CSS rules.
|
||||
*/
|
||||
CKEDITOR.getCss = function() {
|
||||
return styles.join( '\n' );
|
||||
};
|
||||
} )();
|
||||
|
||||
// Perform global clean up to free as much memory as possible
|
||||
// when there are no instances left
|
||||
CKEDITOR.on( 'instanceDestroyed', function() {
|
||||
if ( CKEDITOR.tools.isEmpty( this.instances ) )
|
||||
CKEDITOR.fire( 'reset' );
|
||||
} );
|
||||
|
||||
// Load the bootstrap script.
|
||||
CKEDITOR.loader.load( '_bootstrap' ); // %REMOVE_LINE%
|
||||
|
||||
// Tri-state constants.
|
||||
/**
|
||||
* Used to indicate the ON or ACTIVE state.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
*/
|
||||
CKEDITOR.TRISTATE_ON = 1;
|
||||
|
||||
/**
|
||||
* Used to indicate the OFF or INACTIVE state.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
*/
|
||||
CKEDITOR.TRISTATE_OFF = 2;
|
||||
|
||||
/**
|
||||
* Used to indicate the DISABLED state.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=0]
|
||||
*/
|
||||
CKEDITOR.TRISTATE_DISABLED = 0;
|
||||
|
||||
/**
|
||||
* The editor which is currently active (has user focus).
|
||||
*
|
||||
* function showCurrentEditorName() {
|
||||
* if ( CKEDITOR.currentInstance )
|
||||
* alert( CKEDITOR.currentInstance.name );
|
||||
* else
|
||||
* alert( 'Please focus an editor first.' );
|
||||
* }
|
||||
*
|
||||
* @property {CKEDITOR.editor} currentInstance
|
||||
* @see CKEDITOR#event-currentInstance
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the CKEDITOR.currentInstance object reference changes. This may
|
||||
* happen when setting the focus on different editor instances in the page.
|
||||
*
|
||||
* var editor; // A variable to store a reference to the current editor.
|
||||
* CKEDITOR.on( 'currentInstance', function() {
|
||||
* editor = CKEDITOR.currentInstance;
|
||||
* } );
|
||||
*
|
||||
* @event currentInstance
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the last instance has been destroyed. This event is used to perform
|
||||
* global memory cleanup.
|
||||
*
|
||||
* @event reset
|
||||
*/
|
||||
340
Admin/plugins/ckeditor/core/ckeditor_base.js
Normal file
340
Admin/plugins/ckeditor/core/ckeditor_base.js
Normal file
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Contains the first and essential part of the {@link CKEDITOR}
|
||||
* object definition.
|
||||
*/
|
||||
|
||||
// #### Compressed Code
|
||||
// Compressed code in ckeditor.js must be be updated on changes in the script.
|
||||
// Simply run `grunt ckeditor-base-replace` after changing this file.
|
||||
|
||||
// #### Raw code
|
||||
// ATTENTION: read the above "Compressed Code" notes when changing this code.
|
||||
|
||||
if ( !window.CKEDITOR ) {
|
||||
/**
|
||||
* This is the API entry point. The entire CKEditor code runs under this object.
|
||||
* @class CKEDITOR
|
||||
* @mixins CKEDITOR.event
|
||||
* @singleton
|
||||
*/
|
||||
window.CKEDITOR = ( function() {
|
||||
var basePathSrcPattern = /(^|.*[\\\/])ckeditor\.js(?:\?.*|;.*)?$/i;
|
||||
|
||||
var CKEDITOR = {
|
||||
|
||||
/**
|
||||
* A constant string unique for each release of CKEditor. Its value
|
||||
* is used, by default, to build the URL for all resources loaded
|
||||
* by the editor code, guaranteeing clean cache results when
|
||||
* upgrading.
|
||||
*
|
||||
* alert( CKEDITOR.timestamp ); // e.g. '87dm'
|
||||
*/
|
||||
timestamp: '', // %REMOVE_LINE%
|
||||
/* // %REMOVE_LINE%
|
||||
// The production implementation contains a fixed timestamp, unique
|
||||
// for each release and generated by the releaser.
|
||||
// (Base 36 value of each component of YYMMDDHH - 4 chars total - e.g. 87bm == 08071122)
|
||||
timestamp: '%TIMESTAMP%',
|
||||
// %REMOVE_LINE% */
|
||||
|
||||
/**
|
||||
* Contains the CKEditor version number.
|
||||
*
|
||||
* alert( CKEDITOR.version ); // e.g. 'CKEditor 3.4.1'
|
||||
*/
|
||||
version: '%VERSION%',
|
||||
|
||||
/**
|
||||
* Contains the CKEditor revision number.
|
||||
* The revision number is incremented automatically, following each
|
||||
* modification to the CKEditor source code.
|
||||
*
|
||||
* alert( CKEDITOR.revision ); // e.g. '3975'
|
||||
*/
|
||||
revision: '%REV%',
|
||||
|
||||
/**
|
||||
* A 3-digit random integer, valid for the entire life of the CKEDITOR object.
|
||||
*
|
||||
* alert( CKEDITOR.rnd ); // e.g. 319
|
||||
*
|
||||
* Generated integer is not cryptographically secure. It has been deprecated to
|
||||
* prevent using it in a security-sensitive context by accident.
|
||||
* Use `window.crypto.getRandomValues()` native browser method instead.
|
||||
*
|
||||
* @deprecated 4.18.0
|
||||
* @property {Number}
|
||||
*/
|
||||
rnd: Math.floor( Math.random() * ( 999 /*Max*/ - 100 /*Min*/ + 1 ) ) + 100 /*Min*/,
|
||||
|
||||
/**
|
||||
* Private object used to hold core stuff. It should not be used outside of
|
||||
* the API code as properties defined here may change at any time
|
||||
* without notice.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_: {
|
||||
pending: [],
|
||||
basePathSrcPattern: basePathSrcPattern
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates the API loading status. The following statuses are available:
|
||||
*
|
||||
* * **unloaded**: the API is not yet loaded.
|
||||
* * **basic_loaded**: the basic API features are available.
|
||||
* * **basic_ready**: the basic API is ready to load the full core code.
|
||||
* * **loaded**: the API can be fully used.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* if ( CKEDITOR.status == 'loaded' ) {
|
||||
* // The API can now be fully used.
|
||||
* doSomething();
|
||||
* } else {
|
||||
* // Wait for the full core to be loaded and fire its loading.
|
||||
* CKEDITOR.on( 'load', doSomething );
|
||||
* CKEDITOR.loadFullCore && CKEDITOR.loadFullCore();
|
||||
* }
|
||||
*/
|
||||
status: 'unloaded',
|
||||
|
||||
/**
|
||||
* The full URL for the CKEditor installation directory.
|
||||
* It is possible to manually provide the base path by setting a
|
||||
* global variable named `CKEDITOR_BASEPATH`. This global variable
|
||||
* must be set **before** the editor script loading.
|
||||
*
|
||||
* alert( CKEDITOR.basePath ); // e.g. 'http://www.example.com/ckeditor/'
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
basePath: ( function() {
|
||||
// Find out the editor directory path, based on its <script> tag.
|
||||
var path = window.CKEDITOR_BASEPATH || '';
|
||||
|
||||
if ( !path ) {
|
||||
var scripts = document.getElementsByTagName( 'script' );
|
||||
|
||||
for ( var i = 0; i < scripts.length; i++ ) {
|
||||
var match = scripts[ i ].src.match( basePathSrcPattern );
|
||||
|
||||
if ( match ) {
|
||||
path = match[ 1 ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In IE (only) the script.src string is the raw value entered in the
|
||||
// HTML source. Other browsers return the full resolved URL instead.
|
||||
if ( path.indexOf( ':/' ) == -1 && path.slice( 0, 2 ) != '//' ) {
|
||||
// Absolute path.
|
||||
if ( path.indexOf( '/' ) === 0 )
|
||||
path = location.href.match( /^.*?:\/\/[^\/]*/ )[ 0 ] + path;
|
||||
// Relative path.
|
||||
else
|
||||
path = location.href.match( /^[^\?]*\/(?:)/ )[ 0 ] + path;
|
||||
}
|
||||
|
||||
if ( !path )
|
||||
throw 'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';
|
||||
|
||||
return path;
|
||||
} )(),
|
||||
|
||||
/**
|
||||
* Gets the full URL for CKEditor resources. By default, URLs
|
||||
* returned by this function contain a querystring parameter ("t")
|
||||
* set to the {@link CKEDITOR#timestamp} value.
|
||||
*
|
||||
* It is possible to provide a custom implementation of this
|
||||
* function by setting a global variable named `CKEDITOR_GETURL`.
|
||||
* This global variable must be set **before** the editor script
|
||||
* loading. If the custom implementation returns nothing (`==null`), the
|
||||
* default implementation is used.
|
||||
*
|
||||
* // e.g. 'http://www.example.com/ckeditor/skins/default/editor.css?t=87dm'
|
||||
* alert( CKEDITOR.getUrl( 'skins/default/editor.css' ) );
|
||||
*
|
||||
* // e.g. 'http://www.example.com/skins/default/editor.css?t=87dm'
|
||||
* alert( CKEDITOR.getUrl( '/skins/default/editor.css' ) );
|
||||
*
|
||||
* // e.g. 'http://www.somesite.com/skins/default/editor.css?t=87dm'
|
||||
* alert( CKEDITOR.getUrl( 'http://www.somesite.com/skins/default/editor.css' ) );
|
||||
*
|
||||
* @param {String} resource The resource whose full URL we want to get.
|
||||
* It may be a full, absolute, or relative URL.
|
||||
* @returns {String} The full URL.
|
||||
*/
|
||||
getUrl: function( resource ) {
|
||||
// If this is not a full or absolute path.
|
||||
if ( resource.indexOf( ':/' ) == -1 && resource.indexOf( '/' ) !== 0 )
|
||||
resource = this.basePath + resource;
|
||||
|
||||
resource = this.appendTimestamp( resource );
|
||||
|
||||
return resource;
|
||||
},
|
||||
|
||||
/**
|
||||
* Appends {@link CKEDITOR#timestamp} to the provided URL as querystring parameter ("t").
|
||||
*
|
||||
* Leaves the URL unchanged if it is a directory URL or it already contains querystring parameter.
|
||||
*
|
||||
* @since 4.17.2
|
||||
* @param {String} resource The resource URL to which the timestamp should be appended.
|
||||
* @returns {String} The resource URL with cache key appended whenever possible.
|
||||
*/
|
||||
appendTimestamp: function( resource ) {
|
||||
if ( !this.timestamp ||
|
||||
resource.charAt( resource.length - 1 ) === '/' ||
|
||||
( /[&?]t=/ ).test( resource )
|
||||
) {
|
||||
return resource;
|
||||
}
|
||||
|
||||
var concatenateSign = resource.indexOf( '?' ) >= 0 ? '&' : '?';
|
||||
return resource + concatenateSign + 't=' + this.timestamp;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specify a function to execute when the DOM is fully loaded.
|
||||
*
|
||||
* If called after the DOM has been initialized, the function passed in will
|
||||
* be executed immediately.
|
||||
*
|
||||
* @method
|
||||
* @todo
|
||||
*/
|
||||
domReady: ( function() {
|
||||
// Based on the original jQuery code (available under the MIT license, see LICENSE.md).
|
||||
|
||||
var callbacks = [];
|
||||
|
||||
function onReady() {
|
||||
try {
|
||||
// Cleanup functions for the document ready method
|
||||
if ( document.addEventListener ) {
|
||||
document.removeEventListener( 'DOMContentLoaded', onReady, false );
|
||||
window.removeEventListener( 'load', onReady, false );
|
||||
executeCallbacks();
|
||||
}
|
||||
// Make sure body exists, at least, in case IE gets a little overzealous.
|
||||
else if ( document.attachEvent && document.readyState === 'complete' ) {
|
||||
document.detachEvent( 'onreadystatechange', onReady );
|
||||
window.detachEvent( 'onload', onReady );
|
||||
executeCallbacks();
|
||||
}
|
||||
} catch ( er ) {}
|
||||
}
|
||||
|
||||
function executeCallbacks() {
|
||||
var i;
|
||||
while ( ( i = callbacks.shift() ) )
|
||||
i();
|
||||
}
|
||||
|
||||
return function( fn ) {
|
||||
callbacks.push( fn );
|
||||
|
||||
// Catch cases where this is called after the
|
||||
// browser event has already occurred.
|
||||
if ( document.readyState === 'complete' )
|
||||
// Handle it asynchronously to allow scripts the opportunity to delay ready
|
||||
setTimeout( onReady, 1 );
|
||||
|
||||
// Run below once on demand only.
|
||||
if ( callbacks.length != 1 )
|
||||
return;
|
||||
|
||||
// For IE>8, Firefox, Opera and Webkit.
|
||||
if ( document.addEventListener ) {
|
||||
// Use the handy event callback
|
||||
document.addEventListener( 'DOMContentLoaded', onReady, false );
|
||||
|
||||
// A fallback to window.onload, that will always work
|
||||
window.addEventListener( 'load', onReady, false );
|
||||
|
||||
}
|
||||
// If old IE event model is used
|
||||
else if ( document.attachEvent ) {
|
||||
// ensure firing before onload,
|
||||
// maybe late but safe also for iframes
|
||||
document.attachEvent( 'onreadystatechange', onReady );
|
||||
|
||||
// A fallback to window.onload, that will always work
|
||||
window.attachEvent( 'onload', onReady );
|
||||
|
||||
// If IE and not a frame
|
||||
// continually check to see if the document is ready
|
||||
// use the trick by Diego Perini
|
||||
// http://javascript.nwbox.com/IEContentLoaded/
|
||||
var toplevel = false;
|
||||
|
||||
try {
|
||||
toplevel = !window.frameElement;
|
||||
} catch ( e ) {}
|
||||
|
||||
if ( document.documentElement.doScroll && toplevel ) {
|
||||
scrollCheck();
|
||||
}
|
||||
}
|
||||
|
||||
function scrollCheck() {
|
||||
try {
|
||||
document.documentElement.doScroll( 'left' );
|
||||
} catch ( e ) {
|
||||
setTimeout( scrollCheck, 1 );
|
||||
return;
|
||||
}
|
||||
onReady();
|
||||
}
|
||||
};
|
||||
|
||||
} )()
|
||||
};
|
||||
|
||||
// Make it possible to override the "url" function with a custom
|
||||
// implementation pointing to a global named CKEDITOR_GETURL.
|
||||
var newGetUrl = window.CKEDITOR_GETURL;
|
||||
if ( newGetUrl ) {
|
||||
var originalGetUrl = CKEDITOR.getUrl;
|
||||
CKEDITOR.getUrl = function( resource ) {
|
||||
return newGetUrl.call( CKEDITOR, resource ) || originalGetUrl.call( CKEDITOR, resource );
|
||||
};
|
||||
}
|
||||
|
||||
return CKEDITOR;
|
||||
} )();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function called upon loading a custom configuration file that can
|
||||
* modify the editor instance configuration ({@link CKEDITOR.editor#config}).
|
||||
* It is usually defined inside the custom configuration files that can
|
||||
* include developer defined settings.
|
||||
*
|
||||
* // This is supposed to be placed in the config.js file.
|
||||
* CKEDITOR.editorConfig = function( config ) {
|
||||
* // Define changes to default configuration here. For example:
|
||||
* config.language = 'fr';
|
||||
* config.uiColor = '#AADC6E';
|
||||
* };
|
||||
*
|
||||
* @method editorConfig
|
||||
* @param {CKEDITOR.config} config A configuration object containing the
|
||||
* settings defined for a {@link CKEDITOR.editor} instance up to this
|
||||
* function call. Note that not all settings may still be available. See
|
||||
* [Configuration Loading Order](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_configuration.html)
|
||||
* for details.
|
||||
*/
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR )
|
||||
94
Admin/plugins/ckeditor/core/ckeditor_basic.js
Normal file
94
Admin/plugins/ckeditor/core/ckeditor_basic.js
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Contains the second part of the {@link CKEDITOR} object
|
||||
* definition, which defines the basic editor features to be available in
|
||||
* the root ckeditor_basic.js file.
|
||||
*/
|
||||
|
||||
if ( CKEDITOR.status == 'unloaded' ) {
|
||||
( function() {
|
||||
CKEDITOR.event.implementOn( CKEDITOR );
|
||||
|
||||
/**
|
||||
* Forces the full CKEditor core code, in the case only the basic code has been
|
||||
* loaded (`ckeditor_basic.js`). This method self-destroys (becomes undefined) in
|
||||
* the first call or as soon as the full code is available.
|
||||
*
|
||||
* // Check if the full core code has been loaded and load it.
|
||||
* if ( CKEDITOR.loadFullCore )
|
||||
* CKEDITOR.loadFullCore();
|
||||
*
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.loadFullCore = function() {
|
||||
// If the basic code is not ready, just mark it to be loaded.
|
||||
if ( CKEDITOR.status != 'basic_ready' ) {
|
||||
CKEDITOR.loadFullCore._load = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Destroy this function.
|
||||
delete CKEDITOR.loadFullCore;
|
||||
|
||||
// Append the script to the head.
|
||||
var script = document.createElement( 'script' );
|
||||
script.type = 'text/javascript';
|
||||
script.src = CKEDITOR.basePath + 'ckeditor.js';
|
||||
script.src = CKEDITOR.basePath + 'ckeditor_source.js'; // %REMOVE_LINE%
|
||||
|
||||
document.getElementsByTagName( 'head' )[ 0 ].appendChild( script );
|
||||
};
|
||||
|
||||
/**
|
||||
* The time to wait (in seconds) to load the full editor code after the
|
||||
* page load, if the "ckeditor_basic" file is used. If set to zero, the
|
||||
* editor is loaded on demand, as soon as an instance is created.
|
||||
*
|
||||
* This value must be set on the page before the page load completion.
|
||||
*
|
||||
* // Loads the full source after five seconds.
|
||||
* CKEDITOR.loadFullCoreTimeout = 5;
|
||||
*
|
||||
* @property
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.loadFullCoreTimeout = 0;
|
||||
|
||||
// Documented at ckeditor.js.
|
||||
CKEDITOR.add = function( editor ) {
|
||||
// For now, just put the editor in the pending list. It will be
|
||||
// processed as soon as the full code gets loaded.
|
||||
var pending = this._.pending || ( this._.pending = [] );
|
||||
pending.push( editor );
|
||||
};
|
||||
|
||||
( function() {
|
||||
var onload = function() {
|
||||
var loadFullCore = CKEDITOR.loadFullCore,
|
||||
loadFullCoreTimeout = CKEDITOR.loadFullCoreTimeout;
|
||||
|
||||
if ( !loadFullCore )
|
||||
return;
|
||||
|
||||
CKEDITOR.status = 'basic_ready';
|
||||
|
||||
if ( loadFullCore && loadFullCore._load )
|
||||
loadFullCore();
|
||||
else if ( loadFullCoreTimeout ) {
|
||||
setTimeout( function() {
|
||||
if ( CKEDITOR.loadFullCore )
|
||||
CKEDITOR.loadFullCore();
|
||||
}, loadFullCoreTimeout * 1000 );
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.domReady( onload );
|
||||
} )();
|
||||
|
||||
CKEDITOR.status = 'basic_loaded';
|
||||
} )();
|
||||
}
|
||||
197
Admin/plugins/ckeditor/core/ckeditor_version-check.js
Normal file
197
Admin/plugins/ckeditor/core/ckeditor_version-check.js
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/* global console */
|
||||
|
||||
( function() {
|
||||
var apiUrl = 'https://cke4.ckeditor.com/ckeditor4-secure-version/versions.json',
|
||||
upgradeLink = 'https://ckeditor.com/ckeditor-4-support/',
|
||||
versionRegex = /^4\.(\d+)\.(\d+)(-lts)?(?: \(?.+?\)?)?$/,
|
||||
isDrupal = 'Drupal' in window,
|
||||
consoleErrorDisplayed = false,
|
||||
versionInfo = {
|
||||
current: parseVersion( CKEDITOR.version )
|
||||
};
|
||||
|
||||
if ( isDrupal || !versionInfo.current ) {
|
||||
return;
|
||||
}
|
||||
|
||||
CKEDITOR.config.versionCheck = versionInfo.current.isLts ? false : true;
|
||||
|
||||
CKEDITOR.on( 'instanceReady', function( evt ) {
|
||||
var editor = evt.editor;
|
||||
|
||||
if ( !editor.config.versionCheck ) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.on( 'dialogShow', function( evt ) {
|
||||
var dialog = evt.data;
|
||||
|
||||
if ( dialog._.name !== 'about' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
performVersionCheck( function() {
|
||||
addInfoToAboutDialog( editor, dialog );
|
||||
} );
|
||||
} );
|
||||
|
||||
performVersionCheck( function() {
|
||||
notifyAboutInsecureVersion( editor );
|
||||
} );
|
||||
} );
|
||||
|
||||
function performVersionCheck( callback ) {
|
||||
if ( versionInfo.secure && versionInfo.latest ) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
try {
|
||||
var request = new XMLHttpRequest(),
|
||||
requestUrl = apiUrl + '?v=' + encodeURIComponent( versionInfo.current.original );
|
||||
|
||||
request.onreadystatechange = function() {
|
||||
if ( request.readyState === 4 && request.status === 200 ) {
|
||||
var response = JSON.parse( request.responseText );
|
||||
|
||||
versionInfo.latest = parseVersion( response.latestVersion );
|
||||
versionInfo.secure = parseVersion( response.secureVersion );
|
||||
versionInfo.isLatest = isLatestVersion();
|
||||
versionInfo.isSecure = isSecureVersion();
|
||||
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
request.open( 'GET', requestUrl );
|
||||
request.responseType = 'text';
|
||||
request.send();
|
||||
} catch ( e ) {
|
||||
}
|
||||
}
|
||||
|
||||
function notifyAboutInsecureVersion( editor ) {
|
||||
if ( versionInfo.isSecure ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var notificationMessage = editor.lang.versionCheck.notificationMessage.replace( '%current', versionInfo.current.original ).
|
||||
replace( '%latest', versionInfo.latest.original ).
|
||||
replace( /%link/g, upgradeLink ),
|
||||
isNotificationAvailable = 'notification' in editor.plugins;
|
||||
|
||||
showConsoleError( editor );
|
||||
|
||||
if ( isNotificationAvailable ) {
|
||||
editor.showNotification( notificationMessage, 'warning' );
|
||||
}
|
||||
}
|
||||
|
||||
function showConsoleError( editor ) {
|
||||
if ( !window.console || !window.console.error ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( consoleErrorDisplayed ) {
|
||||
return;
|
||||
}
|
||||
|
||||
consoleErrorDisplayed = true;
|
||||
|
||||
var consoleMessage = editor.lang.versionCheck.consoleMessage.replace( '%current', versionInfo.current.original ).
|
||||
replace( '%latest', versionInfo.latest.original ).
|
||||
replace( /%link/g, upgradeLink );
|
||||
|
||||
console.error( consoleMessage );
|
||||
}
|
||||
|
||||
function addInfoToAboutDialog( editor, dialog ) {
|
||||
var container = dialog.getElement().findOne( '.cke_about_version-check' ),
|
||||
message = getAboutMessage( editor );
|
||||
|
||||
container.setHtml( '' );
|
||||
|
||||
if ( editor.config.versionCheck ) {
|
||||
container.setStyle( 'color', versionInfo.isSecure ? '' : '#C83939' );
|
||||
container.setHtml( message );
|
||||
}
|
||||
}
|
||||
|
||||
function getAboutMessage( editor ) {
|
||||
var lang = editor.lang.versionCheck,
|
||||
msg = '';
|
||||
|
||||
if ( !versionInfo.isLatest ) {
|
||||
msg = lang.aboutDialogUpgradeMessage;
|
||||
}
|
||||
|
||||
if ( !versionInfo.isSecure ) {
|
||||
msg = lang.aboutDialogInsecureMessage;
|
||||
}
|
||||
|
||||
return msg.replace( '%current', versionInfo.current.original ).
|
||||
replace( '%latest', versionInfo.latest.original ).
|
||||
replace( /%link/g, upgradeLink );
|
||||
}
|
||||
|
||||
function isLatestVersion() {
|
||||
return versionInfo.current.minor === versionInfo.latest.minor &&
|
||||
versionInfo.current.patch === versionInfo.latest.patch;
|
||||
}
|
||||
|
||||
function isSecureVersion() {
|
||||
if ( versionInfo.current.minor > versionInfo.secure.minor ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( versionInfo.current.minor === versionInfo.secure.minor &&
|
||||
versionInfo.current.patch >= versionInfo.secure.patch ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function parseVersion( version ) {
|
||||
var parts = version.match( versionRegex );
|
||||
|
||||
if ( !parts ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
original: version,
|
||||
major: 4,
|
||||
minor: Number( parts[ 1 ] ),
|
||||
patch: Number( parts[ 2 ] ),
|
||||
isLts: !!parts[ 3 ]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The version check feature adds a notification system to the editor that informs
|
||||
* users if the editor version is secure. It is highly recommended to stay up to
|
||||
* date with the editor version to ensure that the editor is secure and provides
|
||||
* the best editing experience to users.
|
||||
*
|
||||
* If the current version is below the latest published secure version,
|
||||
* a user will be prompted about the available update. This feature is integrated
|
||||
* with the [Notification](https://ckeditor.com/cke4/addon/notification) plugin,
|
||||
* the [About](https://ckeditor.com/cke4/addon/about) dialog,
|
||||
* and developer console logs.
|
||||
*
|
||||
* You can manually disable this feature by setting the option to `false`,
|
||||
* but we strongly recommend upgrading the editor instead.
|
||||
*
|
||||
* - For CKEditor 4.22.* and below, this option is enabled by default.
|
||||
* - For CKEditor 4 LTS (4.23.0 and above), this option is disabled by default.
|
||||
*
|
||||
* @cfg {Boolean} [versionCheck]
|
||||
* @since 4.22.0
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
} )();
|
||||
275
Admin/plugins/ckeditor/core/command.js
Normal file
275
Admin/plugins/ckeditor/core/command.js
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a command that can be executed on an editor instance.
|
||||
*
|
||||
* var command = new CKEDITOR.command( editor, {
|
||||
* exec: function( editor ) {
|
||||
* alert( editor.document.getBody().getHtml() );
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.commandDefinition
|
||||
* @mixins CKEDITOR.event
|
||||
* @constructor Creates a command class instance.
|
||||
* @param {CKEDITOR.editor} editor The editor instance this command will be
|
||||
* related to.
|
||||
* @param {CKEDITOR.commandDefinition} commandDefinition The command
|
||||
* definition.
|
||||
*/
|
||||
CKEDITOR.command = function( editor, commandDefinition ) {
|
||||
/**
|
||||
* Lists UI items that are associated to this command. This list can be
|
||||
* used to interact with the UI on command execution (by the execution code
|
||||
* itself, for example).
|
||||
*
|
||||
* alert( 'Number of UI items associated to this command: ' + command.uiItems.length );
|
||||
*/
|
||||
this.uiItems = [];
|
||||
|
||||
/**
|
||||
* Executes the command.
|
||||
*
|
||||
* command.exec(); // The command gets executed.
|
||||
*
|
||||
* **Note:** You should use the {@link CKEDITOR.editor#execCommand} method instead of calling
|
||||
* `command.exec()` directly.
|
||||
*
|
||||
* @param {Object} [data] Any data to pass to the command. Depends on the
|
||||
* command implementation and requirements.
|
||||
* @returns {Boolean} A boolean indicating that the command has been successfully executed.
|
||||
*/
|
||||
this.exec = function( data ) {
|
||||
if ( this.state == CKEDITOR.TRISTATE_DISABLED || !this.checkAllowed() )
|
||||
return false;
|
||||
|
||||
if ( this.editorFocus ) // Give editor focus if necessary (https://dev.ckeditor.com/ticket/4355).
|
||||
editor.focus();
|
||||
|
||||
if ( this.fire( 'exec' ) === false )
|
||||
return true;
|
||||
|
||||
return ( commandDefinition.exec.call( this, editor, data ) !== false );
|
||||
};
|
||||
|
||||
/**
|
||||
* Explicitly update the status of the command, by firing the {@link CKEDITOR.command#event-refresh} event,
|
||||
* as well as invoke the {@link CKEDITOR.commandDefinition#refresh} method if defined, this method
|
||||
* is to allow different parts of the editor code to contribute in command status resolution.
|
||||
*
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
* @param {CKEDITOR.dom.elementPath} path
|
||||
*/
|
||||
this.refresh = function( editor, path ) {
|
||||
// Do nothing is we're on read-only and this command doesn't support it.
|
||||
// We don't need to disabled the command explicitely here, because this
|
||||
// is already done by the "readOnly" event listener.
|
||||
if ( !this.readOnly && editor.readOnly )
|
||||
return true;
|
||||
|
||||
// Disable commands that are not allowed in the current selection path context.
|
||||
if ( this.context && !path.isContextFor( this.context ) ) {
|
||||
this.disable();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Disable commands that are not allowed by the active filter.
|
||||
if ( !this.checkAllowed( true ) ) {
|
||||
this.disable();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make the "enabled" state a default for commands enabled from start.
|
||||
if ( !this.startDisabled )
|
||||
this.enable();
|
||||
|
||||
// Disable commands which shouldn't be enabled in this mode.
|
||||
if ( this.modes && !this.modes[ editor.mode ] )
|
||||
this.disable();
|
||||
|
||||
if ( this.fire( 'refresh', { editor: editor, path: path } ) === false )
|
||||
return true;
|
||||
|
||||
return ( commandDefinition.refresh && commandDefinition.refresh.apply( this, arguments ) !== false );
|
||||
};
|
||||
|
||||
var allowed;
|
||||
|
||||
/**
|
||||
* Checks whether this command is allowed by the active allowed
|
||||
* content filter ({@link CKEDITOR.editor#activeFilter}). This means
|
||||
* that if command implements {@link CKEDITOR.feature} interface it will be tested
|
||||
* by the {@link CKEDITOR.filter#checkFeature} method.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {Boolean} [noCache] Skip cache for example due to active filter change. Since CKEditor 4.2.0.
|
||||
* @returns {Boolean} Whether this command is allowed.
|
||||
*/
|
||||
this.checkAllowed = function( noCache ) {
|
||||
if ( !noCache && typeof allowed == 'boolean' )
|
||||
return allowed;
|
||||
|
||||
return allowed = editor.activeFilter.checkFeature( this );
|
||||
};
|
||||
|
||||
CKEDITOR.tools.extend( this, commandDefinition, {
|
||||
/**
|
||||
* The editor modes within which the command can be executed. The
|
||||
* execution will have no action if the current mode is not listed
|
||||
* in this property.
|
||||
*
|
||||
* // Enable the command in both WYSIWYG and Source modes.
|
||||
* command.modes = { wysiwyg:1,source:1 };
|
||||
*
|
||||
* // Enable the command in Source mode only.
|
||||
* command.modes = { source:1 };
|
||||
*
|
||||
* @see CKEDITOR.editor#mode
|
||||
*/
|
||||
modes: { wysiwyg: 1 },
|
||||
|
||||
/**
|
||||
* Indicates that the editor will get the focus before executing
|
||||
* the command.
|
||||
*
|
||||
* // Do not force the editor to have focus when executing the command.
|
||||
* command.editorFocus = false;
|
||||
*
|
||||
* @property {Boolean} [=true]
|
||||
*/
|
||||
editorFocus: 1,
|
||||
|
||||
/**
|
||||
* Indicates that this command is sensible to the selection context.
|
||||
* If `true`, the {@link CKEDITOR.command#method-refresh} method will be
|
||||
* called for this command on the {@link CKEDITOR.editor#event-selectionChange} event.
|
||||
*
|
||||
* @property {Boolean} [=false]
|
||||
*/
|
||||
contextSensitive: !!commandDefinition.context,
|
||||
|
||||
/**
|
||||
* Indicates the editor state. Possible values are:
|
||||
*
|
||||
* * {@link CKEDITOR#TRISTATE_DISABLED}: the command is
|
||||
* disabled. It's execution will have no effect. Same as {@link #disable}.
|
||||
* * {@link CKEDITOR#TRISTATE_ON}: the command is enabled
|
||||
* and currently active in the editor (for context sensitive commands, for example).
|
||||
* * {@link CKEDITOR#TRISTATE_OFF}: the command is enabled
|
||||
* and currently inactive in the editor (for context sensitive commands, for example).
|
||||
*
|
||||
* Do not set this property directly, using the {@link #setState} method instead.
|
||||
*
|
||||
* if ( command.state == CKEDITOR.TRISTATE_DISABLED )
|
||||
* alert( 'This command is disabled' );
|
||||
*
|
||||
* @property {Number} [=CKEDITOR.TRISTATE_DISABLED]
|
||||
*/
|
||||
state: CKEDITOR.TRISTATE_DISABLED
|
||||
} );
|
||||
|
||||
// Call the CKEDITOR.event constructor to initialize this instance.
|
||||
CKEDITOR.event.call( this );
|
||||
};
|
||||
|
||||
CKEDITOR.command.prototype = {
|
||||
/**
|
||||
* Enables the command for execution. The command state (see
|
||||
* {@link CKEDITOR.command#property-state}) available before disabling it is restored.
|
||||
*
|
||||
* command.enable();
|
||||
* command.exec(); // Execute the command.
|
||||
*/
|
||||
enable: function() {
|
||||
if ( this.state == CKEDITOR.TRISTATE_DISABLED && this.checkAllowed() )
|
||||
this.setState( ( !this.preserveState || ( typeof this.previousState == 'undefined' ) ) ? CKEDITOR.TRISTATE_OFF : this.previousState );
|
||||
},
|
||||
|
||||
/**
|
||||
* Disables the command for execution. The command state (see
|
||||
* {@link CKEDITOR.command#property-state}) will be set to {@link CKEDITOR#TRISTATE_DISABLED}.
|
||||
*
|
||||
* command.disable();
|
||||
* command.exec(); // "false" - Nothing happens.
|
||||
*/
|
||||
disable: function() {
|
||||
this.setState( CKEDITOR.TRISTATE_DISABLED );
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the command state.
|
||||
*
|
||||
* command.setState( CKEDITOR.TRISTATE_ON );
|
||||
* command.exec(); // Execute the command.
|
||||
* command.setState( CKEDITOR.TRISTATE_DISABLED );
|
||||
* command.exec(); // 'false' - Nothing happens.
|
||||
* command.setState( CKEDITOR.TRISTATE_OFF );
|
||||
* command.exec(); // Execute the command.
|
||||
*
|
||||
* @param {Number} newState The new state. See {@link #property-state}.
|
||||
* @returns {Boolean} Returns `true` if the command state changed.
|
||||
*/
|
||||
setState: function( newState ) {
|
||||
// Do nothing if there is no state change.
|
||||
if ( this.state == newState )
|
||||
return false;
|
||||
|
||||
if ( newState != CKEDITOR.TRISTATE_DISABLED && !this.checkAllowed() )
|
||||
return false;
|
||||
|
||||
this.previousState = this.state;
|
||||
|
||||
// Set the new state.
|
||||
this.state = newState;
|
||||
|
||||
// Fire the "state" event, so other parts of the code can react to the
|
||||
// change.
|
||||
this.fire( 'state' );
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the on/off (active/inactive) state of the command. This is
|
||||
* mainly used internally by context sensitive commands.
|
||||
*
|
||||
* command.toggleState();
|
||||
*/
|
||||
toggleState: function() {
|
||||
if ( this.state == CKEDITOR.TRISTATE_OFF )
|
||||
this.setState( CKEDITOR.TRISTATE_ON );
|
||||
else if ( this.state == CKEDITOR.TRISTATE_ON )
|
||||
this.setState( CKEDITOR.TRISTATE_OFF );
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.event.implementOn( CKEDITOR.command.prototype );
|
||||
|
||||
/**
|
||||
* Indicates the previous command state.
|
||||
*
|
||||
* alert( command.previousState );
|
||||
*
|
||||
* @property {Number} previousState
|
||||
* @see #state
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the command state changes.
|
||||
*
|
||||
* command.on( 'state', function() {
|
||||
* // Alerts the new state.
|
||||
* alert( this.state );
|
||||
* } );
|
||||
*
|
||||
* @event state
|
||||
*/
|
||||
|
||||
/**
|
||||
* @event refresh
|
||||
* @todo
|
||||
*/
|
||||
162
Admin/plugins/ckeditor/core/commanddefinition.js
Normal file
162
Admin/plugins/ckeditor/core/commanddefinition.js
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.commandDefinition} class
|
||||
* which contains the defintion of a command. This file is for
|
||||
* documentation purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Virtual class that illustrates the features of command objects to be
|
||||
* passed to the {@link CKEDITOR.editor#addCommand} function.
|
||||
*
|
||||
* @class CKEDITOR.commandDefinition
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* The function to be fired when the commend is executed.
|
||||
*
|
||||
* editorInstance.addCommand( 'sample', {
|
||||
* exec: function( editor ) {
|
||||
* alert( 'Executing a command for the editor name "' + editor.name + '"!' );
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* @method exec
|
||||
* @param {CKEDITOR.editor} editor The editor within which to run the command.
|
||||
* @param {Object} [data] Additional data to be used to execute the command.
|
||||
* @returns {Boolean} Whether the command has been successfully executed.
|
||||
* Defaults to `true` if nothing is returned.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether the command needs to be hooked into the redo/undo system.
|
||||
*
|
||||
* editorInstance.addCommand( 'alertName', {
|
||||
* exec: function( editor ) {
|
||||
* alert( editor.name );
|
||||
* },
|
||||
* canUndo: false // No support for undo/redo.
|
||||
* } );
|
||||
*
|
||||
* @property {Boolean} [canUndo=true]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether the command is asynchronous, which means that the
|
||||
* {@link CKEDITOR.editor#event-afterCommandExec} event will be fired by the
|
||||
* command itself manually, and that the return value of this command is not to
|
||||
* be returned by the {@link #exec} function.
|
||||
*
|
||||
* editorInstance.addCommand( 'loadoptions', {
|
||||
* exec: function( editor ) {
|
||||
* var cmd = this;
|
||||
* // Asynchronous operation below.
|
||||
* CKEDITOR.ajax.loadXml( 'data.xml', function() {
|
||||
* editor.fire( 'afterCommandExec', {
|
||||
* name: 'loadoptions',
|
||||
* command: cmd
|
||||
* } );
|
||||
* } );
|
||||
* },
|
||||
* async: true // The command needs some time to complete after the exec function returns.
|
||||
* } );
|
||||
*
|
||||
* @property {Boolean} [async=false]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether the command should give focus to the editor before execution.
|
||||
*
|
||||
* editorInstance.addCommand( 'maximize', {
|
||||
* exec: function( editor ) {
|
||||
* // ...
|
||||
* },
|
||||
* editorFocus: false // The command does not require focusing the editing document.
|
||||
* } );
|
||||
*
|
||||
* See also {@link CKEDITOR.command#editorFocus}.
|
||||
*
|
||||
* @property {Boolean} [editorFocus=true]
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Whether the command state should be set to {@link CKEDITOR#TRISTATE_DISABLED} on startup.
|
||||
*
|
||||
* editorInstance.addCommand( 'unlink', {
|
||||
* exec: function( editor ) {
|
||||
* // ...
|
||||
* },
|
||||
* startDisabled: true // The command is unavailable until the selection is inside a link.
|
||||
* } );
|
||||
*
|
||||
* @property {Boolean} [startDisabled=false]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that this command is sensitive to the selection context.
|
||||
* If `true`, the {@link CKEDITOR.command#method-refresh} method will be
|
||||
* called for this command on selection changes, with a single parameter
|
||||
* representing the current elements path.
|
||||
*
|
||||
* @property {Boolean} [contextSensitive=true]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defined by the command definition, a function to determine the command state. It will be invoked
|
||||
* when the editor has its `states` or `selection` changed.
|
||||
*
|
||||
* **Note:** The function provided must be calling {@link CKEDITOR.command#setState} in all circumstances
|
||||
* if it is intended to update the command state.
|
||||
*
|
||||
* @method refresh
|
||||
* @param {CKEDITOR.editor} editor
|
||||
* @param {CKEDITOR.dom.elementPath} path
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the element name used to reflect the command state on selection changes.
|
||||
* If the selection is in a place where the element is not allowed, the command
|
||||
* will be disabled.
|
||||
* Setting this property overrides {@link #contextSensitive} to `true`.
|
||||
*
|
||||
* @property {Boolean} [context=true]
|
||||
*/
|
||||
|
||||
/**
|
||||
* The editor modes within which the command can be executed. The execution
|
||||
* will have no action if the current mode is not listed in this property.
|
||||
*
|
||||
* editorInstance.addCommand( 'link', {
|
||||
* exec: function( editor ) {
|
||||
* // ...
|
||||
* },
|
||||
* modes: { wysiwyg:1 } // The command is available in wysiwyg mode only.
|
||||
* } );
|
||||
*
|
||||
* See also {@link CKEDITOR.command#modes}.
|
||||
*
|
||||
* @property {Object} [modes={ wysiwyg:1 }]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether the command should be enabled in the {@link CKEDITOR.editor#setReadOnly read-only mode}.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @property {Boolean} [readOnly=false]
|
||||
*/
|
||||
|
||||
/**
|
||||
* A property that should be set when a command has no keystroke assigned by {@link CKEDITOR.editor#setKeystroke}, but
|
||||
* the keystroke is still supported. For example: `cut`, `copy` and `paste` commands are handled that way.
|
||||
* This property is used when displaying keystroke information in tooltips and context menus. It is used by
|
||||
* {@link CKEDITOR.editor#getCommandKeystroke}.
|
||||
*
|
||||
* @since 4.6.0
|
||||
* @property {Number} fakeKeystroke
|
||||
*/
|
||||
453
Admin/plugins/ckeditor/core/config.js
Normal file
453
Admin/plugins/ckeditor/core/config.js
Normal file
@@ -0,0 +1,453 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.config} object that stores the
|
||||
* default configuration settings.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used in conjunction with the {@link CKEDITOR.config#enterMode}
|
||||
* and {@link CKEDITOR.config#shiftEnterMode} configuration
|
||||
* settings to make the editor produce `<p>` tags when
|
||||
* using the <kbd>Enter</kbd> key.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.ENTER_P = 1;
|
||||
|
||||
/**
|
||||
* Used in conjunction with the {@link CKEDITOR.config#enterMode}
|
||||
* and {@link CKEDITOR.config#shiftEnterMode} configuration
|
||||
* settings to make the editor produce `<br>` tags when
|
||||
* using the <kbd>Enter</kbd> key.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.ENTER_BR = 2;
|
||||
|
||||
/**
|
||||
* Used in conjunction with the {@link CKEDITOR.config#enterMode}
|
||||
* and {@link CKEDITOR.config#shiftEnterMode} configuration
|
||||
* settings to make the editor produce `<div>` tags when
|
||||
* using the <kbd>Enter</kbd> key.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=3]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.ENTER_DIV = 3;
|
||||
|
||||
/**
|
||||
* Stores default configuration settings. Changes to this object are
|
||||
* reflected in all editor instances, if not specified otherwise for a particular
|
||||
* instance.
|
||||
*
|
||||
* Read more about setting CKEditor configuration in the
|
||||
* {@glink guide/dev_configuration documentation}.
|
||||
*
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.config = {
|
||||
/**
|
||||
* The URL path to the custom configuration file to be loaded. If not
|
||||
* overwritten with inline configuration, it defaults to the `config.js`
|
||||
* file present in the root of the CKEditor installation directory.
|
||||
*
|
||||
* CKEditor will recursively load custom configuration files defined inside
|
||||
* other custom configuration files.
|
||||
*
|
||||
* Read more about setting CKEditor configuration in the
|
||||
* {@glink guide/dev_configuration documentation}.
|
||||
*
|
||||
* // Load a specific configuration file.
|
||||
* CKEDITOR.replace( 'myfield', { customConfig: '/myconfig.js' } );
|
||||
*
|
||||
* // Do not load any custom configuration file.
|
||||
* CKEDITOR.replace( 'myfield', { customConfig: '' } );
|
||||
*
|
||||
* @cfg {String} [="<CKEditor folder>/config.js"]
|
||||
*/
|
||||
customConfig: 'config.js',
|
||||
|
||||
/**
|
||||
* Whether the element replaced by the editor (usually a `<textarea>`)
|
||||
* is to be updated automatically when posting the form containing the editor.
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
autoUpdateElement: true,
|
||||
|
||||
/**
|
||||
* The user interface language localization to use. If left empty, the editor
|
||||
* will automatically be localized to the user language. If the user language is not supported,
|
||||
* the language specified in the {@link CKEDITOR.config#defaultLanguage}
|
||||
* configuration setting is used.
|
||||
*
|
||||
* Read more in the {@glink features/uilanguage documentation} and see the
|
||||
* {@glink examples/uilanguages example}.
|
||||
*
|
||||
* // Load the German interface.
|
||||
* config.language = 'de';
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
language: '',
|
||||
|
||||
/**
|
||||
* The language to be used if the {@link CKEDITOR.config#language}
|
||||
* setting is left empty and it is not possible to localize the editor to the user language.
|
||||
*
|
||||
* Read more in the {@glink features/uilanguage documentation} and see the
|
||||
* {@glink examples/uilanguages example}.
|
||||
*
|
||||
* config.defaultLanguage = 'it';
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
defaultLanguage: 'en',
|
||||
|
||||
/**
|
||||
* The writing direction of the language which is used to create editor content.
|
||||
* Allowed values are:
|
||||
*
|
||||
* * `''` (an empty string) – Indicates that content direction will be the same as either
|
||||
* the editor UI direction or the page element direction depending on the editor type:
|
||||
* * {@glink guide/dev_framed Classic editor} – The same as the user interface language direction.
|
||||
* * {@glink guide/dev_inline Inline editor}– The same as the editable element text direction.
|
||||
* * `'ltr'` – Indicates a Left-To-Right text direction (like in English).
|
||||
* * `'rtl'` – Indicates a Right-To-Left text direction (like in Arabic).
|
||||
*
|
||||
* See the {@glink examples/language example}.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* config.contentsLangDirection = 'rtl';
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
contentsLangDirection: '',
|
||||
|
||||
/**
|
||||
* Sets the behavior of the <kbd>Enter</kbd> key. It also determines other behavior
|
||||
* rules of the editor, like whether the `<br>` element is to be used
|
||||
* as a paragraph separator when indenting text.
|
||||
* The allowed values are the following constants that cause the behavior outlined below:
|
||||
*
|
||||
* * {@link CKEDITOR#ENTER_P} (1) – New `<p>` paragraphs are created.
|
||||
* * {@link CKEDITOR#ENTER_BR} (2) – Lines are broken with `<br>` elements.
|
||||
* * {@link CKEDITOR#ENTER_DIV} (3) – New `<div>` blocks are created.
|
||||
*
|
||||
* **Note**: It is recommended to use the {@link CKEDITOR#ENTER_P} setting because of
|
||||
* its semantic value and correctness. The editor is optimized for this setting.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* // Not recommended.
|
||||
* config.enterMode = CKEDITOR.ENTER_BR;
|
||||
*
|
||||
* @cfg {Number} [=CKEDITOR.ENTER_P]
|
||||
*/
|
||||
enterMode: CKEDITOR.ENTER_P,
|
||||
|
||||
/**
|
||||
* Forces the use of {@link CKEDITOR.config#enterMode} as line break regardless
|
||||
* of the context. If, for example, {@link CKEDITOR.config#enterMode} is set
|
||||
* to {@link CKEDITOR#ENTER_P}, pressing the <kbd>Enter</kbd> key inside a
|
||||
* `<div>` element will create a new paragraph with a `<p>`
|
||||
* instead of a `<div>`.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* // Not recommended.
|
||||
* config.forceEnterMode = true;
|
||||
*
|
||||
* @since 3.2.1
|
||||
* @cfg
|
||||
*/
|
||||
forceEnterMode: false,
|
||||
|
||||
/**
|
||||
* Similarly to the {@link CKEDITOR.config#enterMode} setting, it defines the behavior
|
||||
* of the <kbd>Shift+Enter</kbd> key combination.
|
||||
*
|
||||
* The allowed values are the following constants that cause the behavior outlined below:
|
||||
*
|
||||
* * {@link CKEDITOR#ENTER_P} (1) – New `<p>` paragraphs are created.
|
||||
* * {@link CKEDITOR#ENTER_BR} (2) – Lines are broken with `<br>` elements.
|
||||
* * {@link CKEDITOR#ENTER_DIV} (3) – New `<div>` blocks are created.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* config.shiftEnterMode = CKEDITOR.ENTER_P;
|
||||
*
|
||||
* @cfg {Number} [=CKEDITOR.ENTER_BR]
|
||||
*/
|
||||
shiftEnterMode: CKEDITOR.ENTER_BR,
|
||||
|
||||
/**
|
||||
* Sets the `DOCTYPE` to be used when loading the editor content as HTML.
|
||||
*
|
||||
* // Set the DOCTYPE to the HTML 4 (Quirks) mode.
|
||||
* config.docType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
docType: '<!DOCTYPE html>',
|
||||
|
||||
/**
|
||||
* Sets the `id` attribute to be used on the `body` element
|
||||
* of the editing area. This can be useful when you intend to reuse the original CSS
|
||||
* file you are using on your live website and want to assign the editor the same ID
|
||||
* as the section that will include the contents. In this way ID-specific CSS rules will
|
||||
* be enabled.
|
||||
*
|
||||
* config.bodyId = 'contents_id';
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @cfg
|
||||
*/
|
||||
bodyId: '',
|
||||
|
||||
/**
|
||||
* Sets the `class` attribute to be used on the `body` element
|
||||
* of the editing area. This can be useful when you intend to reuse the original CSS
|
||||
* file you are using on your live website and want to assign the editor the same class
|
||||
* as the section that will include the contents. In this way class-specific CSS rules will
|
||||
* be enabled.
|
||||
*
|
||||
* config.bodyClass = 'contents';
|
||||
*
|
||||
* **Note:** The editor needs to load stylesheets containing contents styles. You can either
|
||||
* copy them to the `contents.css` file that the editor loads by default or set the {@link #contentsCss}
|
||||
* option.
|
||||
*
|
||||
* **Note:** This setting only applies to {@glink guide/dev_framed classic editor} (the one that uses `iframe`).
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @cfg
|
||||
*/
|
||||
bodyClass: '',
|
||||
|
||||
/**
|
||||
* Indicates whether the content to be edited is being input as a full HTML page.
|
||||
* A full page includes the `<html>`, `<head>`, and `<body>` elements.
|
||||
* The final output will also reflect this setting, including the
|
||||
* `<body>` content only if this setting is disabled.
|
||||
*
|
||||
* Read more in the {@glink features/fullpage documentation} and see the
|
||||
* {@glink examples/fullpage example}.
|
||||
*
|
||||
* config.fullPage = true;
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @cfg
|
||||
*/
|
||||
fullPage: false,
|
||||
|
||||
/**
|
||||
* The height of the editing area that includes the editor content. This configuration
|
||||
* option accepts an integer (to denote a value in pixels) or any CSS-defined length unit
|
||||
* except percent (`%`) values which are not supported.
|
||||
*
|
||||
* **Note:** This configuration option is ignored by {@glink guide/dev_inline inline editor}.
|
||||
*
|
||||
* Read more in the {@glink features/size documentation} and see the
|
||||
* {@glink examples/size example}.
|
||||
*
|
||||
* config.height = 500; // 500 pixels.
|
||||
* config.height = '25em'; // CSS length.
|
||||
* config.height = '300px'; // CSS length.
|
||||
*
|
||||
* @cfg {Number/String}
|
||||
*/
|
||||
height: 200,
|
||||
|
||||
/**
|
||||
* The CSS file(s) to be used to apply style to editor content. It should
|
||||
* reflect the CSS used in the target pages where the content is to be
|
||||
* displayed.
|
||||
*
|
||||
* **Note:** This configuration value is used only in {@glink guide/dev_framed `<iframe>`-based editor }
|
||||
* and ignored by {@glink guide/dev_inline inline editor}
|
||||
* as it uses the styles that come directly from the page that CKEditor is
|
||||
* rendered on. It is also ignored in the {@link #fullPage full page mode} in
|
||||
* which the developer has full control over the page HTML code.
|
||||
*
|
||||
* Read more in the {@glink features/styles documentation} and see the
|
||||
* {@glink examples/styles example}.
|
||||
*
|
||||
* config.contentsCss = '/css/mysitestyles.css';
|
||||
* config.contentsCss = [ '/css/mysitestyles.css', '/css/anotherfile.css' ];
|
||||
*
|
||||
* @cfg {String/Array} [contentsCss=CKEDITOR.getUrl( 'contents.css' )]
|
||||
*/
|
||||
contentsCss: CKEDITOR.getUrl( 'contents.css' ),
|
||||
|
||||
/**
|
||||
* Comma-separated list of plugins to be used in an editor instance. Note that
|
||||
* the actual plugins that are to be loaded could still be affected by two other settings:
|
||||
* {@link CKEDITOR.config#extraPlugins} and {@link CKEDITOR.config#removePlugins}.
|
||||
*
|
||||
* @cfg {String/String[]} [="<default list of plugins>"]
|
||||
*/
|
||||
plugins: '', // %REMOVE_LINE%
|
||||
|
||||
/**
|
||||
* A list of additional plugins to be loaded. This setting makes it easier
|
||||
* to add new plugins without having to touch the {@link CKEDITOR.config#plugins} setting.
|
||||
*
|
||||
* **Note:** The most recommended way to
|
||||
* [add CKEditor plugins](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_plugins.html) is through
|
||||
* [CKEditor Builder](https://ckeditor.com/cke4/builder). Read more in the
|
||||
* {@glink guide/dev_plugins documentation}.
|
||||
*
|
||||
* config.extraPlugins = 'myplugin,anotherplugin';
|
||||
*
|
||||
* @cfg {String/String[]}
|
||||
*/
|
||||
extraPlugins: '',
|
||||
|
||||
/**
|
||||
* A list of plugins that must not be loaded. This setting makes it possible
|
||||
* to avoid loading some plugins defined in the {@link CKEDITOR.config#plugins}
|
||||
* setting without having to touch it.
|
||||
*
|
||||
* **Note:** A plugin required by another plugin cannot be removed and will cause
|
||||
* an error to be thrown. So for example if `contextmenu` is required by `tabletools`,
|
||||
* it can only be removed if `tabletools` is not loaded.
|
||||
*
|
||||
* config.removePlugins = 'elementspath,save,font';
|
||||
*
|
||||
* @cfg {String/String[]}
|
||||
*/
|
||||
removePlugins: '',
|
||||
|
||||
/**
|
||||
* A list of regular expressions to be executed on input HTML,
|
||||
* indicating HTML source code that when matched, must **not** be available in the WYSIWYG
|
||||
* mode for editing.
|
||||
*
|
||||
* config.protectedSource.push( /<\?[\s\S]*?\?>/g ); // PHP code
|
||||
* config.protectedSource.push( /<%[\s\S]*?%>/g ); // ASP code
|
||||
* config.protectedSource.push( /(<asp:[^\>]+>[\s|\S]*?<\/asp:[^\>]+>)|(<asp:[^\>]+\/>)/gi ); // ASP.NET code
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
protectedSource: [],
|
||||
|
||||
/**
|
||||
* The editor `tabindex` value.
|
||||
*
|
||||
* Read more in the {@glink features/tabindex documentation} and see the
|
||||
* {@glink examples/tabindex example}.
|
||||
*
|
||||
* config.tabIndex = 1;
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
tabIndex: 0,
|
||||
|
||||
/**
|
||||
* Indicates that some of the editor features, like alignment and text
|
||||
* direction, should use the "computed value" of the feature to indicate its
|
||||
* on/off state instead of using the "real value".
|
||||
*
|
||||
* If enabled in a Left-To-Right written document, the "Left Justify"
|
||||
* alignment button will be shown as active, even if the alignment style is not
|
||||
* explicitly applied to the current paragraph in the editor.
|
||||
*
|
||||
* config.useComputedState = false;
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @cfg {Boolean} [useComputedState=true]
|
||||
*/
|
||||
useComputedState: true,
|
||||
|
||||
/**
|
||||
* The editor UI outer width. This configuration option accepts an integer
|
||||
* (to denote a value in pixels) or any CSS-defined length unit.
|
||||
*
|
||||
* Unlike the {@link CKEDITOR.config#height} setting, this
|
||||
* one will set the outer width of the entire editor UI, not for the
|
||||
* editing area only.
|
||||
*
|
||||
* **Note:** This configuration option is ignored by {@glink guide/dev_inline inline editor}.
|
||||
*
|
||||
* Read more in the {@glink features/size documentation} and see the
|
||||
* {@glink examples/size example}.
|
||||
*
|
||||
* config.width = 850; // 850 pixels wide.
|
||||
* config.width = '75%'; // CSS unit.
|
||||
*
|
||||
* @cfg {String/Number}
|
||||
*/
|
||||
width: '',
|
||||
|
||||
/**
|
||||
* The base Z-index for floating dialog windows and popups.
|
||||
*
|
||||
* config.baseFloatZIndex = 2000;
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
baseFloatZIndex: 10000,
|
||||
|
||||
/**
|
||||
* The keystrokes that are blocked by default as the browser implementation
|
||||
* is buggy. These default keystrokes are handled by the editor.
|
||||
*
|
||||
* // Default setting.
|
||||
* config.blockedKeystrokes = [
|
||||
* CKEDITOR.CTRL + 66, // Ctrl+B
|
||||
* CKEDITOR.CTRL + 73, // Ctrl+I
|
||||
* CKEDITOR.CTRL + 85 // Ctrl+U
|
||||
* ];
|
||||
*
|
||||
* @cfg {Array} [blockedKeystrokes=see example]
|
||||
*/
|
||||
blockedKeystrokes: [
|
||||
CKEDITOR.CTRL + 66, // Ctrl+B
|
||||
CKEDITOR.CTRL + 73, // Ctrl+I
|
||||
CKEDITOR.CTRL + 85 // Ctrl+U
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* The base user interface color to be used by the editor. Not all skins are
|
||||
* {@glink guide/skin_sdk_chameleon compatible with this setting}.
|
||||
*
|
||||
* Read more in the {@glink features/uicolor documentation} and see the
|
||||
* {@glink examples/uicolor example}.
|
||||
*
|
||||
* // Using a color code.
|
||||
* config.uiColor = '#AADC6E';
|
||||
*
|
||||
* // Using an HTML color name.
|
||||
* config.uiColor = 'Gold';
|
||||
*
|
||||
* @cfg {String} uiColor
|
||||
*/
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.config )
|
||||
204
Admin/plugins/ckeditor/core/creators/inline.js
Normal file
204
Admin/plugins/ckeditor/core/creators/inline.js
Normal file
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
( function() {
|
||||
/** @class CKEDITOR */
|
||||
|
||||
/**
|
||||
* Turns a DOM element with the `contenteditable` attribute set to `true` into a
|
||||
* CKEditor instance. Check {@link CKEDITOR.dtd#$editable} for a list of
|
||||
* allowed element names.
|
||||
*
|
||||
* **Note:** If the DOM element for which inline editing is being enabled does not have
|
||||
* the `contenteditable` attribute set to `true` or the {@link CKEDITOR.config#readOnly `config.readOnly`}
|
||||
* configuration option is set to `true`, the editor will start in read-only mode.
|
||||
*
|
||||
* <div contenteditable="true" id="content">...</div>
|
||||
* ...
|
||||
* CKEDITOR.inline( 'content' );
|
||||
*
|
||||
* It is also possible to create an inline editor from the `<textarea>` element.
|
||||
* If you do so, an additional `<div>` element with editable content will be created
|
||||
* directly after the `<textarea>` element and the `<textarea>` element will be hidden.
|
||||
*
|
||||
* Since 4.17 this function also supports the {@glink features/delayed_creation Delayed Editor Creation} feature
|
||||
* allowing to postpone the editor initialization.
|
||||
*
|
||||
* Since 4.19 if the editor has been configured to use the {@glink features/delayed_creation Delayed Editor Creation}
|
||||
* feature and the editor has not been initialized yet, this function will return a handle allowing
|
||||
* to cancel the interval set by the {@link CKEDITOR.config#delayIfDetached} and
|
||||
* {@link CKEDITOR.config#delayIfDetached_interval} options.
|
||||
*
|
||||
* ```javascript
|
||||
* var cancelInterval = CKEDITOR.inline( 'editor', {
|
||||
* delayIfDetached: true,
|
||||
* delayIfDetached_interval: 50 // Default value, you can skip that option.
|
||||
* } );
|
||||
*
|
||||
* cancelInterval(); // Cancel editor initialization if needed.
|
||||
* ```
|
||||
*
|
||||
* It is recommended to use this function to prevent potential memory leaks. Use it if you know
|
||||
* that the editor host element will never be attached to the DOM. As an example, execute cancel handle
|
||||
* in your component cleanup logic (e.g. `onDestroy` lifecycle methods in popular frontend frameworks).
|
||||
*
|
||||
* Read more about this feature in the {@glink features/delayed_creation documentation}.
|
||||
*
|
||||
* @param {Object/String} element The DOM element or its ID.
|
||||
* @param {Object} [instanceConfig] The specific configurations to apply to this editor instance.
|
||||
* See {@link CKEDITOR.config}.
|
||||
* @returns {CKEDITOR.editor/Function/null} The editor instance or a cancellation function.
|
||||
* If {@glink features/delayed_creation Delayed Editor Creation} feature has not been set and
|
||||
* element is missing in DOM, this function will return `null`.
|
||||
*/
|
||||
CKEDITOR.inline = function( element, instanceConfig ) {
|
||||
element = CKEDITOR.editor._getEditorElement( element );
|
||||
|
||||
if ( !element ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// (#4461)
|
||||
if ( CKEDITOR.editor.shouldDelayEditorCreation( element, instanceConfig ) ) {
|
||||
return CKEDITOR.editor.initializeDelayedEditorCreation( element, instanceConfig, 'inline' );
|
||||
}
|
||||
|
||||
var textarea = element.is( 'textarea' ) ? element : null,
|
||||
editorData = textarea ? textarea.getValue() : element.getHtml(),
|
||||
editor = new CKEDITOR.editor( instanceConfig, element, CKEDITOR.ELEMENT_MODE_INLINE );
|
||||
|
||||
if ( textarea ) {
|
||||
editor.setData( editorData, null, true );
|
||||
|
||||
//Change element from textarea to div
|
||||
element = CKEDITOR.dom.element.createFromHtml(
|
||||
'<div contenteditable="' + !!editor.readOnly + '" class="cke_textarea_inline">' +
|
||||
textarea.getValue() +
|
||||
'</div>',
|
||||
CKEDITOR.document );
|
||||
|
||||
element.insertAfter( textarea );
|
||||
textarea.hide();
|
||||
|
||||
// Attaching the concrete form.
|
||||
if ( textarea.$.form )
|
||||
editor._attachToForm();
|
||||
} else {
|
||||
// If editor element does not have contenteditable attribute, but config.readOnly
|
||||
// is explicitly set to false, set the contentEditable property to true (#3866).
|
||||
if ( instanceConfig && typeof instanceConfig.readOnly !== 'undefined' && !instanceConfig.readOnly ) {
|
||||
element.setAttribute( 'contenteditable', 'true' );
|
||||
}
|
||||
|
||||
// Initial editor data is simply loaded from the page element content to make
|
||||
// data retrieval possible immediately after the editor creation.
|
||||
editor.setData( editorData, null, true );
|
||||
}
|
||||
|
||||
// Once the editor is loaded, start the UI.
|
||||
editor.on( 'loaded', function() {
|
||||
editor.fire( 'uiReady' );
|
||||
|
||||
// Enable editing on the element.
|
||||
editor.editable( element );
|
||||
|
||||
// Editable itself is the outermost element.
|
||||
editor.container = element;
|
||||
editor.ui.contentsElement = element;
|
||||
|
||||
// Load and process editor data.
|
||||
editor.setData( editor.getData( 1 ) );
|
||||
|
||||
// Clean on startup.
|
||||
editor.resetDirty();
|
||||
|
||||
editor.fire( 'contentDom' );
|
||||
|
||||
// Inline editing defaults to "wysiwyg" mode, so plugins don't
|
||||
// need to make special handling for this "mode-less" environment.
|
||||
editor.mode = 'wysiwyg';
|
||||
editor.fire( 'mode' );
|
||||
|
||||
// The editor is completely loaded for interaction.
|
||||
editor.status = 'ready';
|
||||
editor.fireOnce( 'instanceReady' );
|
||||
CKEDITOR.fire( 'instanceReady', null, editor );
|
||||
|
||||
// give priority to plugins that relay on editor#loaded for bootstrapping.
|
||||
}, null, null, 10000 );
|
||||
|
||||
// Handle editor destroying.
|
||||
editor.on( 'destroy', function() {
|
||||
var container = editor.container;
|
||||
// Remove container from DOM if inline-textarea editor.
|
||||
// Show <textarea> back again.
|
||||
// Editor can be destroyed before container is created (#3115).
|
||||
if ( textarea && container ) {
|
||||
container.clearCustomData();
|
||||
container.remove();
|
||||
}
|
||||
|
||||
if ( textarea ) {
|
||||
textarea.show();
|
||||
}
|
||||
|
||||
editor.element.clearCustomData();
|
||||
|
||||
delete editor.element;
|
||||
} );
|
||||
|
||||
return editor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls the {@link CKEDITOR#inline `CKEDITOR.inline()`} method for all page elements with the `contenteditable` attribute set to
|
||||
* `true` that are allowed in the {@link CKEDITOR.dtd#$editable} object.
|
||||
*
|
||||
* Since 4.17 this function also supports the {@glink features/delayed_creation Delayed Editor Creation} feature
|
||||
* allowing to postpone the editor initialization.
|
||||
* Read more about this feature in the {@glink features/delayed_creation documentation}.
|
||||
*/
|
||||
CKEDITOR.inlineAll = function() {
|
||||
var el,
|
||||
data;
|
||||
|
||||
for ( var name in CKEDITOR.dtd.$editable ) {
|
||||
var elements = CKEDITOR.document.getElementsByTag( name );
|
||||
|
||||
for ( var i = 0, len = elements.count(); i < len; i++ ) {
|
||||
el = elements.getItem( i );
|
||||
|
||||
// Check whether an element is editable and if an editor attached is not to it already (#4293).
|
||||
if ( el.getAttribute( 'contenteditable' ) == 'true' && !el.getEditor() ) {
|
||||
// Fire the "inline" event, making it possible to customize
|
||||
// the instance settings and eventually cancel the creation.
|
||||
|
||||
data = {
|
||||
element: el,
|
||||
config: {}
|
||||
};
|
||||
|
||||
if ( CKEDITOR.fire( 'inline', data ) !== false ) {
|
||||
CKEDITOR.inline( el, data.config );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.domReady( function() {
|
||||
!CKEDITOR.disableAutoInline && CKEDITOR.inlineAll();
|
||||
} );
|
||||
|
||||
} )();
|
||||
|
||||
/**
|
||||
* Disables creating the inline editor automatically for elements with
|
||||
* the `contenteditable` attribute set to `true`.
|
||||
*
|
||||
* CKEDITOR.disableAutoInline = true;
|
||||
*
|
||||
* @cfg {Boolean} [disableAutoInline=false]
|
||||
*/
|
||||
630
Admin/plugins/ckeditor/core/creators/themedui.js
Normal file
630
Admin/plugins/ckeditor/core/creators/themedui.js
Normal file
@@ -0,0 +1,630 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/** @class CKEDITOR */
|
||||
|
||||
/**
|
||||
* The class name used to identify `<textarea>` elements to be replaced
|
||||
* by CKEditor instances. Set it to empty/`null` to disable this feature.
|
||||
*
|
||||
* CKEDITOR.replaceClass = 'rich_editor';
|
||||
*
|
||||
* @cfg {String} [replaceClass='ckeditor']
|
||||
*/
|
||||
CKEDITOR.replaceClass = 'ckeditor';
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Replaces a `<textarea>` or a DOM element (`<div>`) with a CKEditor
|
||||
* instance. For textareas, the initial value in the editor will be the
|
||||
* textarea value. For DOM elements, their `innerHTML` will be used
|
||||
* instead. It is recommended to use `<textarea>` and `<div>` elements only.
|
||||
*
|
||||
* <textarea id="myfield" name="myfield"></textarea>
|
||||
* ...
|
||||
* CKEDITOR.replace( 'myfield' );
|
||||
*
|
||||
* var textarea = document.body.appendChild( document.createElement( 'textarea' ) );
|
||||
* CKEDITOR.replace( textarea );
|
||||
*
|
||||
* Since 4.17 this function also supports the {@glink features/delayed_creation Delayed Editor Creation} feature
|
||||
* allowing to postpone the editor initialization.
|
||||
*
|
||||
* Since 4.19 if the editor has been configured to use the {@glink features/delayed_creation Delayed Editor Creation}
|
||||
* feature and the editor has not been initialized yet, this function will return a handle allowing
|
||||
* to cancel the interval set by the {@link CKEDITOR.config#delayIfDetached} and
|
||||
* {@link CKEDITOR.config#delayIfDetached_interval} options.
|
||||
*
|
||||
* ```javascript
|
||||
* var cancelInterval = CKEDITOR.replace( 'editor', {
|
||||
* delayIfDetached: true,
|
||||
* delayIfDetached_interval: 50 // Default value, you can skip that option.
|
||||
* } );
|
||||
*
|
||||
* cancelInterval(); // Cancel editor initialization if needed.
|
||||
* ```
|
||||
*
|
||||
* It is recommended to use this function to prevent potential memory leaks. Use it if you know
|
||||
* that the editor host element will never be attached to the DOM. As an example, execute cancel handle
|
||||
* in your component cleanup logic (e.g. `onDestroy` lifecycle methods in popular frontend frameworks).
|
||||
*
|
||||
* Read more about this feature in the {@glink features/delayed_creation documentation}.
|
||||
*
|
||||
* @param {Object/String} element The DOM element (textarea), its ID, or name.
|
||||
* @param {Object} [config] The specific configuration to apply to this
|
||||
* editor instance. Configuration set here will override the global CKEditor settings
|
||||
* (see {@link CKEDITOR.config}).
|
||||
* @returns {CKEDITOR.editor/Function/null} The editor instance or a cancellation function.
|
||||
* If {@glink features/delayed_creation Delayed Editor Creation} feature has not been set and
|
||||
* element is missing in DOM, this function will return `null`.
|
||||
*/
|
||||
CKEDITOR.replace = function( element, config ) {
|
||||
return createInstance( element, config, null, CKEDITOR.ELEMENT_MODE_REPLACE );
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new editor instance at the end of a specific DOM element.
|
||||
*
|
||||
* <!DOCTYPE html>
|
||||
* <html>
|
||||
* <head>
|
||||
* <meta charset="utf-8">
|
||||
* <title>CKEditor</title>
|
||||
* <!-- Make sure the path to CKEditor is correct. -->
|
||||
* <script src="/ckeditor/ckeditor.js"></script>
|
||||
* </head>
|
||||
* <body>
|
||||
* <div id="editorSpace"></div>
|
||||
* <script>
|
||||
* CKEDITOR.appendTo( 'editorSpace' );
|
||||
* </script>
|
||||
* </body>
|
||||
* </html>
|
||||
*
|
||||
* Since 4.17 this function also supports the {@glink features/delayed_creation Delayed Editor Creation} feature
|
||||
* allowing to postpone the editor initialization.
|
||||
*
|
||||
* Since 4.19 if the editor has been configured to use the {@glink features/delayed_creation Delayed Editor Creation}
|
||||
* feature and the editor has not been initialized yet, this function will return a handle allowing
|
||||
* to cancel the interval set by the {@link CKEDITOR.config#delayIfDetached} and
|
||||
* {@link CKEDITOR.config#delayIfDetached_interval} options.
|
||||
*
|
||||
* ```javascript
|
||||
* var cancelInterval = CKEDITOR.appendTo( 'editorSpace', {
|
||||
* delayIfDetached: true,
|
||||
* delayIfDetached_interval: 50 // Default value, you can skip that option.
|
||||
* } );
|
||||
*
|
||||
* cancelInterval(); // Cancel editor initialization if needed.
|
||||
* ```
|
||||
*
|
||||
* It is recommended to use this function to prevent potential memory leaks. Use it if you know
|
||||
* that the editor host element will never be attached to the DOM. As an example, execute cancel handle
|
||||
* in your component cleanup logic (e.g. `onDestroy` lifecycle methods in popular frontend frameworks).
|
||||
*
|
||||
* Read more about this feature in the {@glink features/delayed_creation documentation}.
|
||||
*
|
||||
* @param {Object/String} element The DOM element, its ID, or name.
|
||||
* @param {Object} [config] The specific configuration to apply to this
|
||||
* editor instance. Configuration set here will override the global CKEditor settings
|
||||
* (see {@link CKEDITOR.config}).
|
||||
* @param {String} [data] Since 3.3. Initial value for the instance.
|
||||
* @returns {CKEDITOR.editor/Function/null} The editor instance or a cancelation function.
|
||||
* If {@glink features/delayed_creation Delayed Editor Creation} feature has not been set and
|
||||
* element is missing in DOM, this function will return `null`.
|
||||
*/
|
||||
CKEDITOR.appendTo = function( element, config, data ) {
|
||||
return createInstance( element, config, data, CKEDITOR.ELEMENT_MODE_APPENDTO );
|
||||
};
|
||||
|
||||
/**
|
||||
* Replaces all `<textarea>` elements available in the document with
|
||||
* editor instances.
|
||||
*
|
||||
* // Replace all <textarea> elements in the page.
|
||||
* CKEDITOR.replaceAll();
|
||||
*
|
||||
* // Replace all <textarea class="myClassName"> elements in the page.
|
||||
* CKEDITOR.replaceAll( 'myClassName' );
|
||||
*
|
||||
* // Selectively replace <textarea> elements, based on a custom evaluation function.
|
||||
* CKEDITOR.replaceAll( function( textarea, config ) {
|
||||
* // A function that needs to be evaluated for the <textarea>
|
||||
* // to be replaced. It must explicitly return "false" to ignore a
|
||||
* // specific <textarea>.
|
||||
* // You can also customize the editor instance by having the function
|
||||
* // modify the "config" parameter.
|
||||
* } );
|
||||
*
|
||||
* // Full page example where three <textarea> elements are replaced.
|
||||
* <!DOCTYPE html>
|
||||
* <html>
|
||||
* <head>
|
||||
* <meta charset="utf-8">
|
||||
* <title>CKEditor</title>
|
||||
* <!-- Make sure the path to CKEditor is correct. -->
|
||||
* <script src="/ckeditor/ckeditor.js"></script>
|
||||
* </head>
|
||||
* <body>
|
||||
* <textarea name="editor1"></textarea>
|
||||
* <textarea name="editor2"></textarea>
|
||||
* <textarea name="editor3"></textarea>
|
||||
* <script>
|
||||
* // Replace all three <textarea> elements above with CKEditor instances.
|
||||
* CKEDITOR.replaceAll();
|
||||
* </script>
|
||||
* </body>
|
||||
* </html>
|
||||
*
|
||||
* Since 4.17 this function also supports the {@glink features/delayed_creation Delayed Editor Creation} feature
|
||||
* allowing to postpone the editor initialization.
|
||||
* Read more about this feature in the {@glink features/delayed_creation documentation}.
|
||||
*
|
||||
* @param {String} [className] The `<textarea>` class name.
|
||||
* @param {Function} [evaluator] An evaluation function that must return `true` for a `<textarea>`
|
||||
* to be replaced with the editor. If the function returns `false`, the `<textarea>` element
|
||||
* will not be replaced.
|
||||
*/
|
||||
CKEDITOR.replaceAll = function() {
|
||||
var textareas = document.getElementsByTagName( 'textarea' );
|
||||
|
||||
for ( var i = 0; i < textareas.length; i++ ) {
|
||||
var config = null,
|
||||
textarea = textareas[ i ];
|
||||
|
||||
// The "name" and/or "id" attribute must exist.
|
||||
if ( !textarea.name && !textarea.id )
|
||||
continue;
|
||||
|
||||
if ( typeof arguments[ 0 ] == 'string' ) {
|
||||
// The textarea class name could be passed as the function
|
||||
// parameter.
|
||||
|
||||
var classRegex = new RegExp( '(?:^|\\s)' + arguments[ 0 ] + '(?:$|\\s)' );
|
||||
|
||||
if ( !classRegex.test( textarea.className ) )
|
||||
continue;
|
||||
} else if ( typeof arguments[ 0 ] == 'function' ) {
|
||||
// An evaluation function could be passed as the function parameter.
|
||||
// It must explicitly return "false" to ignore a specific <textarea>.
|
||||
config = {};
|
||||
if ( arguments[ 0 ]( textarea, config ) === false )
|
||||
continue;
|
||||
}
|
||||
|
||||
this.replace( textarea, config );
|
||||
}
|
||||
};
|
||||
|
||||
/** @class CKEDITOR.editor */
|
||||
|
||||
/**
|
||||
* Registers an editing mode. This function is to be used mainly by plugins.
|
||||
*
|
||||
* @param {String} mode The mode name.
|
||||
* @param {Function} exec The function that performs the actual mode change.
|
||||
*/
|
||||
CKEDITOR.editor.prototype.addMode = function( mode, exec ) {
|
||||
( this._.modes || ( this._.modes = {} ) )[ mode ] = exec;
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes the editing mode of this editor instance.
|
||||
*
|
||||
* **Note:** The mode switch could be asynchronous depending on the mode provider.
|
||||
* Use the `callback` to hook subsequent code.
|
||||
*
|
||||
* // Switch to "source" view.
|
||||
* CKEDITOR.instances.editor1.setMode( 'source' );
|
||||
* // Switch to "wysiwyg" view and be notified on completion.
|
||||
* CKEDITOR.instances.editor1.setMode( 'wysiwyg', function() { alert( 'wysiwyg mode loaded!' ); } );
|
||||
*
|
||||
* @param {String} [newMode] If not specified, the {@link CKEDITOR.config#startupMode} will be used.
|
||||
* @param {Function} [callback] Optional callback function which is invoked once the mode switch has succeeded.
|
||||
*/
|
||||
CKEDITOR.editor.prototype.setMode = function( newMode, callback ) {
|
||||
var editor = this;
|
||||
|
||||
var modes = this._.modes;
|
||||
|
||||
// Mode loading quickly fails.
|
||||
if ( newMode == editor.mode || !modes || !modes[ newMode ] )
|
||||
return;
|
||||
|
||||
editor.fire( 'beforeSetMode', newMode );
|
||||
|
||||
if ( editor.mode ) {
|
||||
var isDirty = editor.checkDirty(),
|
||||
previousModeData = editor._.previousModeData,
|
||||
currentData,
|
||||
unlockSnapshot = 0;
|
||||
|
||||
editor.fire( 'beforeModeUnload' );
|
||||
|
||||
// Detach the current editable. While detaching editable will set
|
||||
// cached editor's data (with internal setData call). We use this
|
||||
// data below to avoid two getData() calls in a row.
|
||||
editor.editable( 0 );
|
||||
|
||||
editor._.previousMode = editor.mode;
|
||||
// Get cached data, which was set while detaching editable.
|
||||
editor._.previousModeData = currentData = editor.getData( 1 );
|
||||
|
||||
// If data has not been modified in the mode which we are currently leaving,
|
||||
// avoid making snapshot right after initializing new mode.
|
||||
// https://dev.ckeditor.com/ticket/5217#comment:20
|
||||
// Tested by:
|
||||
// 'test switch mode with unrecoreded, inner HTML specific content (boguses)'
|
||||
// 'test switch mode with unrecoreded, inner HTML specific content (boguses) plus changes in source mode'
|
||||
if ( editor.mode == 'source' && previousModeData == currentData ) {
|
||||
// We need to make sure that unlockSnapshot will update the last snapshot
|
||||
// (will not create new one) if lockSnapshot is not called on outdated snapshots stack.
|
||||
// Additionally, forceUpdate prevents from making content image now, which is useless
|
||||
// (because it equals editor data not inner HTML).
|
||||
editor.fire( 'lockSnapshot', { forceUpdate: true } );
|
||||
unlockSnapshot = 1;
|
||||
}
|
||||
|
||||
// Clear up the mode space.
|
||||
editor.ui.space( 'contents' ).setHtml( '' );
|
||||
|
||||
editor.mode = '';
|
||||
} else {
|
||||
editor._.previousModeData = editor.getData( 1 );
|
||||
}
|
||||
|
||||
// Fire the mode handler.
|
||||
this._.modes[ newMode ]( function() {
|
||||
// Set the current mode.
|
||||
editor.mode = newMode;
|
||||
|
||||
if ( isDirty !== undefined )
|
||||
!isDirty && editor.resetDirty();
|
||||
|
||||
if ( unlockSnapshot )
|
||||
editor.fire( 'unlockSnapshot' );
|
||||
// Since snapshot made on dataReady (which normally catches changes done by setData)
|
||||
// won't work because editor.mode was not set yet (it's set in this function), we need
|
||||
// to make special snapshot for changes done in source mode here.
|
||||
else if ( newMode == 'wysiwyg' )
|
||||
editor.fire( 'saveSnapshot' );
|
||||
|
||||
// Delay to avoid race conditions (setMode inside setMode).
|
||||
setTimeout( function() {
|
||||
if ( editor.isDestroyed() || editor.isDetached() ) {
|
||||
return;
|
||||
}
|
||||
editor.fire( 'mode' );
|
||||
callback && callback.call( editor );
|
||||
}, 0 );
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Resizes the editor interface.
|
||||
*
|
||||
* **Note:** Since 4.14.1 this method accepts numeric or absolute CSS length units.
|
||||
*
|
||||
* ```javascript
|
||||
* editor.resize( 900, 300 );
|
||||
*
|
||||
* editor.resize( '5in', 450, true );
|
||||
* ```
|
||||
*
|
||||
* @param {Number/String} width The new width. It can be an integer denoting a value
|
||||
* in pixels or a CSS size value with unit. When null is passed, the value will not be set.
|
||||
* @param {Number/String} height The new height. It can be an integer denoting a value
|
||||
* in pixels or a CSS size value with unit.
|
||||
* @param {Boolean} [isContentHeight] Indicates that the provided height is to
|
||||
* be applied to the editor content area, and not to the entire editor
|
||||
* interface. Defaults to `false`.
|
||||
* @param {Boolean} [resizeInner] Indicates that it is the inner interface
|
||||
* element that must be resized, not the outer element. The default theme
|
||||
* defines the editor interface inside a pair of `<span>` elements
|
||||
* (`<span><span>...</span></span>`). By default the first,
|
||||
* outer `<span>` element receives the sizes. If this parameter is set to
|
||||
* `true`, the second, inner `<span>` is resized instead.
|
||||
*/
|
||||
CKEDITOR.editor.prototype.resize = function( width, height, isContentHeight, resizeInner ) {
|
||||
var container = this.container,
|
||||
contents = this.ui.space( 'contents' ),
|
||||
contentsFrame = CKEDITOR.env.webkit && this.document && this.document.getWindow().$.frameElement,
|
||||
outer;
|
||||
|
||||
if ( resizeInner ) {
|
||||
outer = this.container.getFirst( function( node ) {
|
||||
return node.type == CKEDITOR.NODE_ELEMENT && node.hasClass( 'cke_inner' );
|
||||
} );
|
||||
} else {
|
||||
outer = container;
|
||||
}
|
||||
|
||||
if ( width || width === 0 ) {
|
||||
width = convertCssUnitToPx( width );
|
||||
}
|
||||
|
||||
// Set as border box width. (https://dev.ckeditor.com/ticket/5353)
|
||||
outer.setSize( 'width', width, true );
|
||||
|
||||
// WebKit needs to refresh the iframe size to avoid rendering issues. (1/2) (https://dev.ckeditor.com/ticket/8348)
|
||||
contentsFrame && ( contentsFrame.style.width = '1%' );
|
||||
|
||||
height = convertCssUnitToPx( height );
|
||||
|
||||
// Get the height delta between the outer table and the content area.
|
||||
var contentsOuterDelta = ( outer.$.offsetHeight || 0 ) - ( contents.$.clientHeight || 0 ),
|
||||
|
||||
// If we're setting the content area's height, then we don't need the delta.
|
||||
resultContentsHeight = Math.max( height - ( isContentHeight ? 0 : contentsOuterDelta ), 0 ),
|
||||
resultOuterHeight = ( isContentHeight ? height + contentsOuterDelta : height );
|
||||
|
||||
contents.setStyle( 'height', CKEDITOR.tools.cssLength( resultContentsHeight ) );
|
||||
|
||||
// WebKit needs to refresh the iframe size to avoid rendering issues. (2/2) (https://dev.ckeditor.com/ticket/8348)
|
||||
contentsFrame && ( contentsFrame.style.width = '100%' );
|
||||
|
||||
// Emit a resize event.
|
||||
this.fire( 'resize', {
|
||||
outerHeight: resultOuterHeight,
|
||||
contentsHeight: resultContentsHeight,
|
||||
// Sometimes width is not provided.
|
||||
outerWidth: width || outer.getSize( 'width' )
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the element that can be used to check the editor size. This method
|
||||
* is mainly used by the [Editor Resize](https://ckeditor.com/cke4/addon/resize) plugin, which adds
|
||||
* a UI handle that can be used to resize the editor.
|
||||
*
|
||||
* @param {Boolean} forContents Whether to return the "contents" part of the theme instead of the container.
|
||||
* @returns {CKEDITOR.dom.element} The resizable element.
|
||||
*/
|
||||
CKEDITOR.editor.prototype.getResizable = function( forContents ) {
|
||||
return forContents ? this.ui.space( 'contents' ) : this.container;
|
||||
};
|
||||
|
||||
function convertCssUnitToPx( unit ) {
|
||||
return CKEDITOR.tools.convertToPx( CKEDITOR.tools.cssLength( unit ) );
|
||||
}
|
||||
|
||||
function createInstance( element, config, data, mode ) {
|
||||
element = CKEDITOR.editor._getEditorElement( element );
|
||||
|
||||
if ( !element ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// (#4461)
|
||||
if ( CKEDITOR.editor.shouldDelayEditorCreation( element, config ) ) {
|
||||
return CKEDITOR.editor.initializeDelayedEditorCreation( element, config, 'replace' );
|
||||
}
|
||||
|
||||
// Create the editor instance.
|
||||
var editor = new CKEDITOR.editor( config, element, mode );
|
||||
|
||||
if ( mode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
|
||||
// Do not replace the textarea right now, just hide it. The effective
|
||||
// replacement will be done later in the editor creation lifecycle.
|
||||
element.setStyle( 'visibility', 'hidden' );
|
||||
|
||||
// https://dev.ckeditor.com/ticket/8031 Remember if textarea was required and remove the attribute.
|
||||
editor._.required = element.hasAttribute( 'required' );
|
||||
element.removeAttribute( 'required' );
|
||||
}
|
||||
|
||||
data && editor.setData( data, null, true );
|
||||
|
||||
// Once the editor is loaded, start the UI.
|
||||
editor.on( 'loaded', function() {
|
||||
if ( editor.isDestroyed() || editor.isDetached() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
loadTheme( editor );
|
||||
|
||||
if ( mode == CKEDITOR.ELEMENT_MODE_REPLACE && editor.config.autoUpdateElement && element.$.form )
|
||||
editor._attachToForm();
|
||||
|
||||
editor.setMode( editor.config.startupMode, function() {
|
||||
// Clean on startup.
|
||||
editor.resetDirty();
|
||||
|
||||
// Editor is completely loaded for interaction.
|
||||
editor.status = 'ready';
|
||||
editor.fireOnce( 'instanceReady' );
|
||||
CKEDITOR.fire( 'instanceReady', null, editor );
|
||||
} );
|
||||
} );
|
||||
|
||||
editor.on( 'destroy', destroy );
|
||||
return editor;
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
var editor = this,
|
||||
container = editor.container,
|
||||
element = editor.element;
|
||||
|
||||
if ( container ) {
|
||||
container.clearCustomData();
|
||||
container.remove();
|
||||
}
|
||||
|
||||
if ( element ) {
|
||||
element.clearCustomData();
|
||||
if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
|
||||
element.show();
|
||||
if ( editor._.required )
|
||||
element.setAttribute( 'required', 'required' );
|
||||
}
|
||||
delete editor.element;
|
||||
}
|
||||
}
|
||||
|
||||
function loadTheme( editor ) {
|
||||
var name = editor.name,
|
||||
element = editor.element,
|
||||
elementMode = editor.elementMode;
|
||||
|
||||
// Get the HTML for the predefined spaces.
|
||||
var topHtml = editor.fire( 'uiSpace', { space: 'top', html: '' } ).html;
|
||||
var bottomHtml = editor.fire( 'uiSpace', { space: 'bottom', html: '' } ).html;
|
||||
|
||||
var themedTpl = new CKEDITOR.template(
|
||||
'<{outerEl}' +
|
||||
' id="cke_{name}"' +
|
||||
' class="{id} cke cke_reset cke_chrome cke_editor_{name} cke_{langDir} ' + CKEDITOR.env.cssClass + '" ' +
|
||||
' dir="{langDir}"' +
|
||||
' lang="{langCode}"' +
|
||||
' role="application"' +
|
||||
( editor.applicationTitle ? ' aria-labelledby="cke_{name}_arialbl"' : '' ) +
|
||||
'>' +
|
||||
( editor.applicationTitle ? '<span id="cke_{name}_arialbl" class="cke_voice_label">{voiceLabel}</span>' : '' ) +
|
||||
'<{outerEl} class="cke_inner cke_reset" role="presentation">' +
|
||||
'{topHtml}' +
|
||||
'<{outerEl} id="{contentId}" class="cke_contents cke_reset" role="presentation"></{outerEl}>' +
|
||||
'{bottomHtml}' +
|
||||
'</{outerEl}>' +
|
||||
'</{outerEl}>' );
|
||||
|
||||
var container = CKEDITOR.dom.element.createFromHtml( themedTpl.output( {
|
||||
id: editor.id,
|
||||
name: name,
|
||||
langDir: editor.lang.dir,
|
||||
langCode: editor.langCode,
|
||||
voiceLabel: editor.applicationTitle,
|
||||
topHtml: topHtml ? '<span id="' + editor.ui.spaceId( 'top' ) + '" class="cke_top cke_reset_all" role="presentation" style="height:auto">' + topHtml + '</span>' : '',
|
||||
contentId: editor.ui.spaceId( 'contents' ),
|
||||
bottomHtml: bottomHtml ? '<span id="' + editor.ui.spaceId( 'bottom' ) + '" class="cke_bottom cke_reset_all" role="presentation">' + bottomHtml + '</span>' : '',
|
||||
outerEl: CKEDITOR.env.ie ? 'span' : 'div' // https://dev.ckeditor.com/ticket/9571
|
||||
} ) );
|
||||
|
||||
if ( elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
|
||||
element.hide();
|
||||
container.insertAfter( element );
|
||||
} else {
|
||||
element.append( container );
|
||||
}
|
||||
|
||||
editor.container = container;
|
||||
editor.ui.contentsElement = editor.ui.space( 'contents' );
|
||||
|
||||
// Make top and bottom spaces unelectable, but not content space,
|
||||
// otherwise the editable area would be affected.
|
||||
topHtml && editor.ui.space( 'top' ).unselectable();
|
||||
bottomHtml && editor.ui.space( 'bottom' ).unselectable();
|
||||
|
||||
var width = editor.config.width, height = editor.config.height;
|
||||
if ( width )
|
||||
container.setStyle( 'width', CKEDITOR.tools.cssLength( width ) );
|
||||
|
||||
// The editor height is applied to the contents space.
|
||||
if ( height )
|
||||
editor.ui.space( 'contents' ).setStyle( 'height', CKEDITOR.tools.cssLength( height ) );
|
||||
|
||||
// Disable browser context menu for editor's chrome.
|
||||
container.disableContextMenu();
|
||||
|
||||
// Redirect the focus into editor for webkit. (https://dev.ckeditor.com/ticket/5713)
|
||||
CKEDITOR.env.webkit && container.on( 'focus', function() {
|
||||
editor.focus();
|
||||
} );
|
||||
|
||||
editor.fireOnce( 'uiReady' );
|
||||
}
|
||||
|
||||
// Replace all textareas with the default class name.
|
||||
CKEDITOR.domReady( function() {
|
||||
CKEDITOR.replaceClass && CKEDITOR.replaceAll( CKEDITOR.replaceClass );
|
||||
} );
|
||||
} )();
|
||||
|
||||
/**
|
||||
* The current editing mode. An editing mode basically provides
|
||||
* different ways of editing or viewing the editor content.
|
||||
*
|
||||
* alert( CKEDITOR.instances.editor1.mode ); // (e.g.) 'wysiwyg'
|
||||
*
|
||||
* @readonly
|
||||
* @property {String} mode
|
||||
*/
|
||||
|
||||
/**
|
||||
* The mode to load at the editor startup. It depends on the plugins
|
||||
* loaded. By default, the `wysiwyg` and `source` modes are available.
|
||||
*
|
||||
* config.startupMode = 'source';
|
||||
*
|
||||
* @cfg {String} [startupMode='wysiwyg']
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
CKEDITOR.config.startupMode = 'wysiwyg';
|
||||
|
||||
/**
|
||||
* Fired after the editor instance is resized through
|
||||
* the {@link CKEDITOR.editor#method-resize CKEDITOR.resize} method.
|
||||
*
|
||||
* @event resize
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
* @param {Object} data Available since CKEditor 4.5.0.
|
||||
* @param {Number} data.outerHeight The height of the entire area that the editor covers.
|
||||
* @param {Number} data.contentsHeight Editable area height in pixels.
|
||||
* @param {Number} data.outerWidth The width of the entire area that the editor covers.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired before changing the editing mode. See also
|
||||
* {@link #beforeSetMode} and {@link #event-mode}.
|
||||
*
|
||||
* @event beforeModeUnload
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired before the editor mode is set. See also
|
||||
* {@link #event-mode} and {@link #beforeModeUnload}.
|
||||
*
|
||||
* @since 3.5.3
|
||||
* @event beforeSetMode
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
* @param {String} data The name of the mode which is about to be set.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired after setting the editing mode. See also {@link #beforeSetMode} and {@link #beforeModeUnload}
|
||||
*
|
||||
* @event mode
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the editor (replacing a `<textarea>` which has a `required` attribute) is empty during form submission.
|
||||
*
|
||||
* This event replaces native required fields validation that the browsers cannot
|
||||
* perform when CKEditor replaces `<textarea>` elements.
|
||||
*
|
||||
* You can cancel this event to prevent the page from submitting data.
|
||||
*
|
||||
* editor.on( 'required', function( evt ) {
|
||||
* alert( 'Article content is required.' );
|
||||
* evt.cancel();
|
||||
* } );
|
||||
*
|
||||
* @event required
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the UI space is created. This event allows to modify the top bar or the bottom bar with additional HTML.
|
||||
*
|
||||
* For example, it is used in the [Editor Resize](https://ckeditor.com/cke4/addon/resize) plugin
|
||||
* to add the HTML element used to resize the editor.
|
||||
*
|
||||
* @event uiSpace
|
||||
* @param {Object} data
|
||||
* @param {String} data.space The name of the {@link CKEDITOR.ui#space space} for which the event is fired.
|
||||
* @param {String} data.html HTML string which will be included in the given space.
|
||||
*/
|
||||
70
Admin/plugins/ckeditor/core/dataprocessor.js
Normal file
70
Admin/plugins/ckeditor/core/dataprocessor.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.dataProcessor} class, which
|
||||
* defines the basic structure of data processor objects to be
|
||||
* set to {@link CKEDITOR.editor.dataProcessor}.
|
||||
*/
|
||||
|
||||
/**
|
||||
* If defined, points to the data processor which is responsible for translating
|
||||
* and transforming the editor data on input and output.
|
||||
* Generally it will point to an instance of {@link CKEDITOR.htmlDataProcessor},
|
||||
* which handles HTML data. The editor may also handle other data formats by
|
||||
* using different data processors provided by specific plugins.
|
||||
*
|
||||
* @property {CKEDITOR.dataProcessor} dataProcessor
|
||||
* @member CKEDITOR.editor
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a data processor which is responsible for translating and
|
||||
* transforming the editor data on input and output.
|
||||
*
|
||||
* This class is here for documentation purposes only and is not really part of
|
||||
* the API. It serves as the base ("interface") for data processor implementations.
|
||||
*
|
||||
* @class CKEDITOR.dataProcessor
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* Transforms input data into HTML to be loaded into the editor.
|
||||
* While the editor is able to handle non-HTML data (like BBCode), it can only
|
||||
* handle HTML data at runtime. The role of the data processor is to transform
|
||||
* the input data into HTML through this function.
|
||||
*
|
||||
* // Tranforming BBCode data, with a custom BBCode data processor available.
|
||||
* var data = 'This is [b]an example[/b].';
|
||||
* var html = editor.dataProcessor.toHtml( data ); // '<p>This is <b>an example</b>.</p>'
|
||||
*
|
||||
* @method toHtml
|
||||
* @param {String} data The input data to be transformed.
|
||||
* @param {String} [fixForBody] The tag name to be used if the data must be
|
||||
* fixed because it is supposed to be loaded direcly into the `<body>`
|
||||
* tag. This is generally not used by non-HTML data processors.
|
||||
* @todo fixForBody type - compare to htmlDataProcessor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Transforms HTML into data to be output by the editor, in the format
|
||||
* expected by the data processor.
|
||||
*
|
||||
* While the editor is able to handle non-HTML data (like BBCode), it can only
|
||||
* handle HTML data at runtime. The role of the data processor is to transform
|
||||
* the HTML data contained by the editor into a specific data format through
|
||||
* this function.
|
||||
*
|
||||
* // Tranforming into BBCode data, with a custom BBCode data processor available.
|
||||
* var html = '<p>This is <b>an example</b>.</p>';
|
||||
* var data = editor.dataProcessor.toDataFormat( html ); // 'This is [b]an example[/b].'
|
||||
*
|
||||
* @method toDataFormat
|
||||
* @param {String} html The HTML to be transformed.
|
||||
* @param {String} fixForBody The tag name to be used if the output data is
|
||||
* coming from the `<body>` element and may be eventually fixed for it. This is
|
||||
* generally not used by non-HTML data processors.
|
||||
*/
|
||||
13
Admin/plugins/ckeditor/core/dom.js
Normal file
13
Admin/plugins/ckeditor/core/dom.js
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom} object, which contains DOM
|
||||
* manipulation objects and function.
|
||||
*/
|
||||
|
||||
CKEDITOR.dom = {};
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.dom )
|
||||
53
Admin/plugins/ckeditor/core/dom/comment.js
Normal file
53
Admin/plugins/ckeditor/core/dom/comment.js
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.comment} class, which represents
|
||||
* a DOM comment node.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a DOM comment node.
|
||||
*
|
||||
* var nativeNode = document.createComment( 'Example' );
|
||||
* var comment = new CKEDITOR.dom.comment( nativeNode );
|
||||
*
|
||||
* var comment = new CKEDITOR.dom.comment( 'Example' );
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.dom.node
|
||||
* @constructor Creates a comment class instance.
|
||||
* @param {Object/String} comment A native DOM comment node or a string containing
|
||||
* the text to use to create a new comment node.
|
||||
* @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
|
||||
* the node in case of new node creation. Defaults to the current document.
|
||||
*/
|
||||
CKEDITOR.dom.comment = function( comment, ownerDocument ) {
|
||||
if ( typeof comment == 'string' )
|
||||
comment = ( ownerDocument ? ownerDocument.$ : document ).createComment( comment );
|
||||
|
||||
CKEDITOR.dom.domObject.call( this, comment );
|
||||
};
|
||||
|
||||
CKEDITOR.dom.comment.prototype = new CKEDITOR.dom.node();
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.comment.prototype, {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_COMMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_COMMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_COMMENT,
|
||||
|
||||
/**
|
||||
* Gets the outer HTML of this comment.
|
||||
*
|
||||
* @returns {String} The HTML `<!-- comment value -->`.
|
||||
*/
|
||||
getOuterHtml: function() {
|
||||
return '<!--' + this.$.nodeValue + '-->';
|
||||
}
|
||||
} );
|
||||
328
Admin/plugins/ckeditor/core/dom/document.js
Normal file
328
Admin/plugins/ckeditor/core/dom/document.js
Normal file
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.document} class which
|
||||
* represents a DOM document.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a DOM document.
|
||||
*
|
||||
* var document = new CKEDITOR.dom.document( document );
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.dom.domObject
|
||||
* @constructor Creates a document class instance.
|
||||
* @param {Object} domDocument A native DOM document.
|
||||
*/
|
||||
CKEDITOR.dom.document = function( domDocument ) {
|
||||
CKEDITOR.dom.domObject.call( this, domDocument );
|
||||
};
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.dom.document )
|
||||
|
||||
CKEDITOR.dom.document.prototype = new CKEDITOR.dom.domObject();
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype, {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_DOCUMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_DOCUMENT,
|
||||
|
||||
/**
|
||||
* Appends a CSS file to the document.
|
||||
*
|
||||
* CKEDITOR.document.appendStyleSheet( '/mystyles.css' );
|
||||
*
|
||||
* @param {String} cssFileUrl The CSS file URL.
|
||||
*/
|
||||
appendStyleSheet: function( cssFileUrl ) {
|
||||
cssFileUrl = CKEDITOR.appendTimestamp( cssFileUrl );
|
||||
|
||||
if ( this.$.createStyleSheet )
|
||||
this.$.createStyleSheet( cssFileUrl );
|
||||
else {
|
||||
var link = new CKEDITOR.dom.element( 'link' );
|
||||
link.setAttributes( {
|
||||
rel: 'stylesheet',
|
||||
type: 'text/css',
|
||||
href: cssFileUrl
|
||||
} );
|
||||
|
||||
this.getHead().append( link );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a CSS stylesheet and inserts it into the document.
|
||||
*
|
||||
* @param cssStyleText {String} CSS style text.
|
||||
* @returns {Object} The created DOM native stylesheet object.
|
||||
*/
|
||||
appendStyleText: function( cssStyleText ) {
|
||||
if ( this.$.createStyleSheet ) {
|
||||
var styleSheet = this.$.createStyleSheet( '' );
|
||||
styleSheet.cssText = cssStyleText;
|
||||
} else {
|
||||
var style = new CKEDITOR.dom.element( 'style', this );
|
||||
style.append( new CKEDITOR.dom.text( cssStyleText, this ) );
|
||||
this.getHead().append( style );
|
||||
}
|
||||
|
||||
return styleSheet || style.$.sheet;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a {@link CKEDITOR.dom.element} instance in this document.
|
||||
*
|
||||
* @param {String} name The name of the element.
|
||||
* @param {Object} [attributesAndStyles]
|
||||
* @param {Object} [attributesAndStyles.attributes] Attributes that will be set.
|
||||
* @param {Object} [attributesAndStyles.styles] Styles that will be set.
|
||||
* @returns {CKEDITOR.dom.element}
|
||||
*/
|
||||
createElement: function( name, attribsAndStyles ) {
|
||||
var element = new CKEDITOR.dom.element( name, this );
|
||||
|
||||
if ( attribsAndStyles ) {
|
||||
if ( attribsAndStyles.attributes )
|
||||
element.setAttributes( attribsAndStyles.attributes );
|
||||
|
||||
if ( attribsAndStyles.styles )
|
||||
element.setStyles( attribsAndStyles.styles );
|
||||
}
|
||||
|
||||
return element;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a {@link CKEDITOR.dom.text} instance in this document.
|
||||
*
|
||||
* @param {String} text Value of the text node.
|
||||
* @returns {CKEDITOR.dom.element}
|
||||
*/
|
||||
createText: function( text ) {
|
||||
return new CKEDITOR.dom.text( text, this );
|
||||
},
|
||||
|
||||
/**
|
||||
* Moves the selection focus to this document's window.
|
||||
*/
|
||||
focus: function() {
|
||||
this.getWindow().focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the element that is currently designated as the active element in the document.
|
||||
*
|
||||
* **Note:** Only one element can be active at a time in a document.
|
||||
* An active element does not necessarily have focus,
|
||||
* but an element with focus is always the active element in a document.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.element} Active element or `null` if an IE8-9 bug is encountered.
|
||||
* See [#10030](https://dev.ckeditor.com/ticket/10030).
|
||||
*/
|
||||
getActive: function() {
|
||||
var $active;
|
||||
try {
|
||||
$active = this.$.activeElement;
|
||||
} catch ( e ) {
|
||||
return null;
|
||||
}
|
||||
return new CKEDITOR.dom.element( $active );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets an element based on its ID.
|
||||
*
|
||||
* var element = CKEDITOR.document.getById( 'myElement' );
|
||||
* alert( element.getId() ); // 'myElement'
|
||||
*
|
||||
* @param {String} elementId The element ID.
|
||||
* @returns {CKEDITOR.dom.element} The element instance, or `null` if not found.
|
||||
*/
|
||||
getById: function( elementId ) {
|
||||
var $ = this.$.getElementById( elementId );
|
||||
return $ ? new CKEDITOR.dom.element( $ ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a node based on its address. See {@link CKEDITOR.dom.node#getAddress}.
|
||||
*
|
||||
* @param {Array} address
|
||||
* @param {Boolean} [normalized=false]
|
||||
*/
|
||||
getByAddress: function( address, normalized ) {
|
||||
var $ = this.$.documentElement;
|
||||
|
||||
for ( var i = 0; $ && i < address.length; i++ ) {
|
||||
var target = address[ i ];
|
||||
|
||||
if ( !normalized ) {
|
||||
$ = $.childNodes[ target ];
|
||||
continue;
|
||||
}
|
||||
|
||||
var currentIndex = -1;
|
||||
|
||||
for ( var j = 0; j < $.childNodes.length; j++ ) {
|
||||
var candidate = $.childNodes[ j ];
|
||||
|
||||
if ( normalized === true && candidate.nodeType == 3 && candidate.previousSibling && candidate.previousSibling.nodeType == 3 )
|
||||
continue;
|
||||
|
||||
currentIndex++;
|
||||
|
||||
if ( currentIndex == target ) {
|
||||
$ = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ ? new CKEDITOR.dom.node( $ ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets elements list based on a given tag name.
|
||||
*
|
||||
* @param {String} tagName The element tag name.
|
||||
* @returns {CKEDITOR.dom.nodeList} The nodes list.
|
||||
*/
|
||||
getElementsByTag: function( tagName, namespace ) {
|
||||
if ( !( CKEDITOR.env.ie && ( document.documentMode <= 8 ) ) && namespace )
|
||||
tagName = namespace + ':' + tagName;
|
||||
return new CKEDITOR.dom.nodeList( this.$.getElementsByTagName( tagName ) );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the `<head>` element for this document.
|
||||
*
|
||||
* var element = CKEDITOR.document.getHead();
|
||||
* alert( element.getName() ); // 'head'
|
||||
*
|
||||
* @returns {CKEDITOR.dom.element} The `<head>` element.
|
||||
*/
|
||||
getHead: function() {
|
||||
var head = this.$.getElementsByTagName( 'head' )[ 0 ];
|
||||
if ( !head )
|
||||
head = this.getDocumentElement().append( new CKEDITOR.dom.element( 'head' ), true );
|
||||
else
|
||||
head = new CKEDITOR.dom.element( head );
|
||||
|
||||
return head;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the `<body>` element for this document.
|
||||
*
|
||||
* var element = CKEDITOR.document.getBody();
|
||||
* alert( element.getName() ); // 'body'
|
||||
*
|
||||
* @returns {CKEDITOR.dom.element} The `<body>` element.
|
||||
*/
|
||||
getBody: function() {
|
||||
return new CKEDITOR.dom.element( this.$.body );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the DOM document element for this document.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.element} The DOM document element.
|
||||
*/
|
||||
getDocumentElement: function() {
|
||||
return new CKEDITOR.dom.element( this.$.documentElement );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the window object that stores this document.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.window} The window object.
|
||||
*/
|
||||
getWindow: function() {
|
||||
return new CKEDITOR.dom.window( this.$.parentWindow || this.$.defaultView );
|
||||
},
|
||||
|
||||
/**
|
||||
* Defines the document content through `document.write`. Note that the
|
||||
* previous document content will be lost (cleaned).
|
||||
*
|
||||
* document.write(
|
||||
* '<html>' +
|
||||
* '<head><title>Sample Document</title></head>' +
|
||||
* '<body>Document content created by code.</body>' +
|
||||
* '</html>'
|
||||
* );
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @param {String} html The HTML defining the document content.
|
||||
*/
|
||||
write: function( html ) {
|
||||
// Don't leave any history log in IE. (https://dev.ckeditor.com/ticket/5657)
|
||||
this.$.open( 'text/html', 'replace' );
|
||||
|
||||
// Support for custom document.domain in IE.
|
||||
//
|
||||
// The script must be appended because if placed before the
|
||||
// doctype, IE will go into quirks mode and mess with
|
||||
// the editable, e.g. by changing its default height.
|
||||
if ( CKEDITOR.env.ie )
|
||||
html = html.replace( /(?:^\s*<!DOCTYPE[^>]*?>)|^/i, '$&\n<script data-cke-temp="1">(' + CKEDITOR.tools.fixDomain + ')();</script>' );
|
||||
|
||||
this.$.write( html );
|
||||
this.$.close();
|
||||
},
|
||||
|
||||
/**
|
||||
* Wrapper for `querySelectorAll`. Returns a list of elements within this document that match
|
||||
* the specified `selector`.
|
||||
*
|
||||
* **Note:** The returned list is not a live collection (like the result of native `querySelectorAll`).
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String} selector A valid [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors).
|
||||
* @returns {CKEDITOR.dom.nodeList}
|
||||
*/
|
||||
find: function( selector ) {
|
||||
return new CKEDITOR.dom.nodeList( this.$.querySelectorAll( selector ) );
|
||||
},
|
||||
|
||||
/**
|
||||
* Wrapper for `querySelector`. Returns the first element within this document that matches
|
||||
* the specified `selector`.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String} selector A valid [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors).
|
||||
* @returns {CKEDITOR.dom.element}
|
||||
*/
|
||||
findOne: function( selector ) {
|
||||
var el = this.$.querySelector( selector );
|
||||
|
||||
return el ? new CKEDITOR.dom.element( el ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Internet Explorer 8 only method. It returns a document fragment which has all HTML5 elements enabled.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @private
|
||||
* @returns DocumentFragment
|
||||
*/
|
||||
_getHtml5ShivFrag: function() {
|
||||
var $frag = this.getCustomData( 'html5ShivFrag' );
|
||||
|
||||
if ( !$frag ) {
|
||||
$frag = this.$.createDocumentFragment();
|
||||
CKEDITOR.tools.enableHtml5Elements( $frag, true );
|
||||
this.setCustomData( 'html5ShivFrag', $frag );
|
||||
}
|
||||
|
||||
return $frag;
|
||||
}
|
||||
} );
|
||||
194
Admin/plugins/ckeditor/core/dom/documentfragment.js
Normal file
194
Admin/plugins/ckeditor/core/dom/documentfragment.js
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* DocumentFragment is a "lightweight" or "minimal" Document object. It is
|
||||
* commonly used to extract a portion of the document's tree or to create a new
|
||||
* fragment of the document. Various operations may take document fragment objects
|
||||
* as arguments and result in all the child nodes of the document fragment being
|
||||
* moved to the child list of this node.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a document fragment class instance.
|
||||
* @param {CKEDITOR.dom.document/DocumentFragment} [nodeOrDoc=CKEDITOR.document]
|
||||
*/
|
||||
CKEDITOR.dom.documentFragment = function( nodeOrDoc ) {
|
||||
nodeOrDoc = nodeOrDoc || CKEDITOR.document;
|
||||
|
||||
if ( nodeOrDoc.type == CKEDITOR.NODE_DOCUMENT )
|
||||
this.$ = nodeOrDoc.$.createDocumentFragment();
|
||||
else
|
||||
this.$ = nodeOrDoc;
|
||||
};
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.documentFragment.prototype, CKEDITOR.dom.element.prototype, {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_DOCUMENT_FRAGMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_DOCUMENT_FRAGMENT,
|
||||
|
||||
/**
|
||||
* Inserts the document fragment content after the specified node.
|
||||
*
|
||||
* @param {CKEDITOR.dom.node} node
|
||||
*/
|
||||
insertAfterNode: function( node ) {
|
||||
node = node.$;
|
||||
node.parentNode.insertBefore( this.$, node.nextSibling );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the HTML of this document fragment's children.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @returns {String} The HTML of this document fragment's children.
|
||||
*/
|
||||
getHtml: function() {
|
||||
var container = new CKEDITOR.dom.element( 'div' );
|
||||
|
||||
this.clone( 1, 1 ).appendTo( container );
|
||||
|
||||
return container.getHtml().replace( /\s*data-cke-expando=".*?"/g, '' );
|
||||
}
|
||||
}, true, {
|
||||
'append': 1, 'appendBogus': 1, 'clone': 1, 'getFirst': 1, 'getHtml': 1, 'getLast': 1, 'getParent': 1, 'getNext': 1, 'getPrevious': 1,
|
||||
'appendTo': 1, 'moveChildren': 1, 'insertBefore': 1, 'insertAfterNode': 1, 'replace': 1, 'trim': 1, 'type': 1,
|
||||
'ltrim': 1, 'rtrim': 1, 'getDocument': 1, 'getChildCount': 1, 'getChild': 1, 'getChildren': 1
|
||||
} );
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.documentFragment.prototype, CKEDITOR.dom.document.prototype, true, {
|
||||
'find': 1, 'findOne': 1
|
||||
} );
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method append
|
||||
* @inheritdoc CKEDITOR.dom.element#append
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method appendBogus
|
||||
* @inheritdoc CKEDITOR.dom.element#appendBogus
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method clone
|
||||
* @inheritdoc CKEDITOR.dom.element#clone
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getFirst
|
||||
* @inheritdoc CKEDITOR.dom.element#getFirst
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getLast
|
||||
* @inheritdoc CKEDITOR.dom.element#getLast
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getParent
|
||||
* @inheritdoc CKEDITOR.dom.element#getParent
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getNext
|
||||
* @inheritdoc CKEDITOR.dom.element#getNext
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getPrevious
|
||||
* @inheritdoc CKEDITOR.dom.element#getPrevious
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method appendTo
|
||||
* @inheritdoc CKEDITOR.dom.element#appendTo
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method moveChildren
|
||||
* @inheritdoc CKEDITOR.dom.element#moveChildren
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method insertBefore
|
||||
* @inheritdoc CKEDITOR.dom.element#insertBefore
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method replace
|
||||
* @inheritdoc CKEDITOR.dom.element#replace
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method trim
|
||||
* @inheritdoc CKEDITOR.dom.element#trim
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method ltrim
|
||||
* @inheritdoc CKEDITOR.dom.element#ltrim
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method rtrim
|
||||
* @inheritdoc CKEDITOR.dom.element#rtrim
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getDocument
|
||||
* @inheritdoc CKEDITOR.dom.element#getDocument
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getChildCount
|
||||
* @inheritdoc CKEDITOR.dom.element#getChildCount
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getChild
|
||||
* @inheritdoc CKEDITOR.dom.element#getChild
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getChildren
|
||||
* @inheritdoc CKEDITOR.dom.element#getChildren
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method find
|
||||
* @since 4.12.0
|
||||
* @inheritdoc CKEDITOR.dom.document#find
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method findOne
|
||||
* @since 4.12.0
|
||||
* @inheritdoc CKEDITOR.dom.document#findOne
|
||||
*/
|
||||
275
Admin/plugins/ckeditor/core/dom/domobject.js
Normal file
275
Admin/plugins/ckeditor/core/dom/domobject.js
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.editor} class, which is the base
|
||||
* for other classes representing DOM objects.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a DOM object. This class is not intended to be used directly. It
|
||||
* serves as the base class for other classes representing specific DOM
|
||||
* objects.
|
||||
*
|
||||
* @class
|
||||
* @mixins CKEDITOR.event
|
||||
* @constructor Creates a domObject class instance.
|
||||
* @param {Object} nativeDomObject A native DOM object.
|
||||
*/
|
||||
CKEDITOR.dom.domObject = function( nativeDomObject ) {
|
||||
if ( nativeDomObject ) {
|
||||
/**
|
||||
* The native DOM object represented by this class instance.
|
||||
*
|
||||
* var element = new CKEDITOR.dom.element( 'span' );
|
||||
* alert( element.$.nodeType ); // '1'
|
||||
*
|
||||
* @readonly
|
||||
* @property {Object}
|
||||
*/
|
||||
this.$ = nativeDomObject;
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.dom.domObject.prototype = ( function() {
|
||||
// Do not define other local variables here. We want to keep the native
|
||||
// listener closures as clean as possible.
|
||||
|
||||
var getNativeListener = function( domObject, eventName ) {
|
||||
return function( domEvent ) {
|
||||
// In FF, when reloading the page with the editor focused, it may
|
||||
// throw an error because the CKEDITOR global is not anymore
|
||||
// available. So, we check it here first. (https://dev.ckeditor.com/ticket/2923)
|
||||
if ( typeof CKEDITOR != 'undefined' )
|
||||
domObject.fire( eventName, new CKEDITOR.dom.event( domEvent ) );
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
/**
|
||||
* Gets the private `_` object which is bound to the native
|
||||
* DOM object using {@link #getCustomData}.
|
||||
*
|
||||
* var elementA = new CKEDITOR.dom.element( nativeElement );
|
||||
* elementA.getPrivate().value = 1;
|
||||
* ...
|
||||
* var elementB = new CKEDITOR.dom.element( nativeElement );
|
||||
* elementB.getPrivate().value; // 1
|
||||
*
|
||||
* @returns {Object} The private object.
|
||||
*/
|
||||
getPrivate: function() {
|
||||
var priv;
|
||||
|
||||
// Get the main private object from the custom data. Create it if not defined.
|
||||
if ( !( priv = this.getCustomData( '_' ) ) )
|
||||
this.setCustomData( '_', ( priv = {} ) );
|
||||
|
||||
return priv;
|
||||
},
|
||||
|
||||
// Docs inherited from event.
|
||||
on: function( eventName ) {
|
||||
// We customize the "on" function here. The basic idea is that we'll have
|
||||
// only one listener for a native event, which will then call all listeners
|
||||
// set to the event.
|
||||
|
||||
// Get the listeners holder object.
|
||||
var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
|
||||
|
||||
if ( !nativeListeners ) {
|
||||
nativeListeners = {};
|
||||
this.setCustomData( '_cke_nativeListeners', nativeListeners );
|
||||
}
|
||||
|
||||
// Check if we have a listener for that event.
|
||||
if ( !nativeListeners[ eventName ] ) {
|
||||
var listener = nativeListeners[ eventName ] = getNativeListener( this, eventName );
|
||||
|
||||
if ( this.$.addEventListener )
|
||||
this.$.addEventListener( eventName, listener, !!CKEDITOR.event.useCapture );
|
||||
else if ( this.$.attachEvent )
|
||||
this.$.attachEvent( 'on' + eventName, listener );
|
||||
}
|
||||
|
||||
// Call the original implementation.
|
||||
return CKEDITOR.event.prototype.on.apply( this, arguments );
|
||||
},
|
||||
|
||||
// Docs inherited from event.
|
||||
removeListener: function( eventName ) {
|
||||
// Call the original implementation.
|
||||
CKEDITOR.event.prototype.removeListener.apply( this, arguments );
|
||||
|
||||
// If we don't have listeners for this event, clean the DOM up.
|
||||
if ( !this.hasListeners( eventName ) ) {
|
||||
var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
|
||||
var listener = nativeListeners && nativeListeners[ eventName ];
|
||||
if ( listener ) {
|
||||
if ( this.$.removeEventListener )
|
||||
this.$.removeEventListener( eventName, listener, false );
|
||||
else if ( this.$.detachEvent )
|
||||
this.$.detachEvent( 'on' + eventName, listener );
|
||||
|
||||
delete nativeListeners[ eventName ];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes any listener set on this object.
|
||||
*
|
||||
* To avoid memory leaks we must assure that there are no
|
||||
* references left after the object is no longer needed.
|
||||
*/
|
||||
removeAllListeners: function() {
|
||||
try {
|
||||
var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
|
||||
for ( var eventName in nativeListeners ) {
|
||||
var listener = nativeListeners[ eventName ];
|
||||
if ( this.$.detachEvent ) {
|
||||
this.$.detachEvent( 'on' + eventName, listener );
|
||||
} else if ( this.$.removeEventListener ) {
|
||||
this.$.removeEventListener( eventName, listener, false );
|
||||
}
|
||||
|
||||
delete nativeListeners[ eventName ];
|
||||
}
|
||||
// Catch Edge `Permission denied` error which occurs randomly. Since the error is quite
|
||||
// random, catching allows to continue the code execution and cleanup (#3419).
|
||||
} catch ( error ) {
|
||||
if ( !CKEDITOR.env.edge || error.number !== -2146828218 ) {
|
||||
throw( error );
|
||||
}
|
||||
}
|
||||
|
||||
// Remove events from events object so fire() method will not call
|
||||
// listeners (https://dev.ckeditor.com/ticket/11400).
|
||||
CKEDITOR.event.prototype.removeAllListeners.call( this );
|
||||
}
|
||||
};
|
||||
} )();
|
||||
|
||||
( function( domObjectProto ) {
|
||||
var customData = {};
|
||||
|
||||
CKEDITOR.on( 'reset', function() {
|
||||
customData = {};
|
||||
} );
|
||||
|
||||
/**
|
||||
* Determines whether the specified object is equal to the current object.
|
||||
*
|
||||
* var doc = new CKEDITOR.dom.document( document );
|
||||
* alert( doc.equals( CKEDITOR.document ) ); // true
|
||||
* alert( doc == CKEDITOR.document ); // false
|
||||
*
|
||||
* @param {Object} object The object to compare with the current object.
|
||||
* @returns {Boolean} `true` if the object is equal.
|
||||
*/
|
||||
domObjectProto.equals = function( object ) {
|
||||
// Try/Catch to avoid IE permission error when object is from different document.
|
||||
try {
|
||||
return ( object && object.$ === this.$ );
|
||||
} catch ( er ) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a data slot value for this object. These values are shared by all
|
||||
* instances pointing to that same DOM object.
|
||||
*
|
||||
* **Note:** The created data slot is only guaranteed to be available on this unique DOM node,
|
||||
* thus any wish to continue access to it from other element clones (either created by
|
||||
* clone node or from `innerHtml`) will fail. For such usage please use
|
||||
* {@link CKEDITOR.dom.element#setAttribute} instead.
|
||||
*
|
||||
* **Note**: This method does not work on text nodes prior to Internet Explorer 9.
|
||||
*
|
||||
* var element = new CKEDITOR.dom.element( 'span' );
|
||||
* element.setCustomData( 'hasCustomData', true );
|
||||
*
|
||||
* @param {String} key A key used to identify the data slot.
|
||||
* @param {Object} value The value to set to the data slot.
|
||||
* @returns {CKEDITOR.dom.domObject} This DOM object instance.
|
||||
* @chainable
|
||||
*/
|
||||
domObjectProto.setCustomData = function( key, value ) {
|
||||
var expandoNumber = this.getUniqueId(),
|
||||
dataSlot = customData[ expandoNumber ] || ( customData[ expandoNumber ] = {} );
|
||||
|
||||
dataSlot[ key ] = value;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the value set to a data slot in this object.
|
||||
*
|
||||
* var element = new CKEDITOR.dom.element( 'span' );
|
||||
* alert( element.getCustomData( 'hasCustomData' ) ); // e.g. 'true'
|
||||
* alert( element.getCustomData( 'nonExistingKey' ) ); // null
|
||||
*
|
||||
* @param {String} key The key used to identify the data slot.
|
||||
* @returns {Object} This value set to the data slot.
|
||||
*/
|
||||
domObjectProto.getCustomData = function( key ) {
|
||||
var expandoNumber = this.$[ 'data-cke-expando' ],
|
||||
dataSlot = expandoNumber && customData[ expandoNumber ];
|
||||
|
||||
return ( dataSlot && key in dataSlot ) ? dataSlot[ key ] : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the value in the data slot under the given `key`.
|
||||
*
|
||||
* @param {String} key
|
||||
* @returns {Object} Removed value or `null` if not found.
|
||||
*/
|
||||
domObjectProto.removeCustomData = function( key ) {
|
||||
var expandoNumber = this.$[ 'data-cke-expando' ],
|
||||
dataSlot = expandoNumber && customData[ expandoNumber ],
|
||||
retval, hadKey;
|
||||
|
||||
if ( dataSlot ) {
|
||||
retval = dataSlot[ key ];
|
||||
hadKey = key in dataSlot;
|
||||
delete dataSlot[ key ];
|
||||
}
|
||||
|
||||
return hadKey ? retval : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes any data stored in this object.
|
||||
* To avoid memory leaks we must assure that there are no
|
||||
* references left after the object is no longer needed.
|
||||
*/
|
||||
domObjectProto.clearCustomData = function() {
|
||||
// Clear all event listeners
|
||||
this.removeAllListeners();
|
||||
|
||||
var expandoNumber = this.getUniqueId();
|
||||
expandoNumber && delete customData[ expandoNumber ];
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets an ID that can be used to identify this DOM object in
|
||||
* the running session.
|
||||
*
|
||||
* **Note**: This method does not work on text nodes prior to Internet Explorer 9.
|
||||
*
|
||||
* @returns {Number} A unique ID.
|
||||
*/
|
||||
domObjectProto.getUniqueId = function() {
|
||||
return this.$[ 'data-cke-expando' ] || ( this.$[ 'data-cke-expando' ] = CKEDITOR.tools.getNextNumber() );
|
||||
};
|
||||
|
||||
// Implement CKEDITOR.event.
|
||||
CKEDITOR.event.implementOn( domObjectProto );
|
||||
|
||||
} )( CKEDITOR.dom.domObject.prototype );
|
||||
2272
Admin/plugins/ckeditor/core/dom/element.js
Normal file
2272
Admin/plugins/ckeditor/core/dom/element.js
Normal file
File diff suppressed because it is too large
Load Diff
265
Admin/plugins/ckeditor/core/dom/elementpath.js
Normal file
265
Admin/plugins/ckeditor/core/dom/elementpath.js
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
|
||||
var pathBlockLimitElements = {},
|
||||
pathBlockElements = {},
|
||||
tag;
|
||||
|
||||
// Elements that are considered the "Block limit" in an element path.
|
||||
for ( tag in CKEDITOR.dtd.$blockLimit ) {
|
||||
// Exclude from list roots.
|
||||
if ( !( tag in CKEDITOR.dtd.$list ) )
|
||||
pathBlockLimitElements[ tag ] = 1;
|
||||
}
|
||||
|
||||
// Elements that are considered the "End level Block" in an element path.
|
||||
for ( tag in CKEDITOR.dtd.$block ) {
|
||||
// Exclude block limits, and empty block element, e.g. hr.
|
||||
if ( !( tag in CKEDITOR.dtd.$blockLimit || tag in CKEDITOR.dtd.$empty ) )
|
||||
pathBlockElements[ tag ] = 1;
|
||||
}
|
||||
|
||||
// Check if an element contains any block element.
|
||||
function checkHasBlock( element ) {
|
||||
var childNodes = element.getChildren();
|
||||
|
||||
for ( var i = 0, count = childNodes.count(); i < count; i++ ) {
|
||||
var child = childNodes.getItem( i );
|
||||
|
||||
if ( child.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$block[ child.getName() ] )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the list of nodes walked from the start node up to the editable element of the editor.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates an element path class instance.
|
||||
* @param {CKEDITOR.dom.element} startNode From which the path should start.
|
||||
* @param {CKEDITOR.dom.element} root To which element the path should stop, defaults to the `body` element.
|
||||
*/
|
||||
CKEDITOR.dom.elementPath = function( startNode, root ) {
|
||||
var block = null,
|
||||
blockLimit = null,
|
||||
elements = [],
|
||||
e = startNode,
|
||||
elementName;
|
||||
|
||||
// Backward compact.
|
||||
root = root || startNode.getDocument().getBody();
|
||||
|
||||
// Assign root value if startNode is null (#424)(https://dev.ckeditor.com/ticket/17028).
|
||||
if ( !e ) {
|
||||
e = root;
|
||||
}
|
||||
|
||||
do {
|
||||
if ( e.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
elements.push( e );
|
||||
|
||||
if ( !this.lastElement ) {
|
||||
this.lastElement = e;
|
||||
|
||||
// If an object or non-editable element is fully selected at the end of the element path,
|
||||
// it must not become the block limit.
|
||||
if ( e.is( CKEDITOR.dtd.$object ) || e.getAttribute( 'contenteditable' ) == 'false' )
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( e.equals( root ) )
|
||||
break;
|
||||
|
||||
if ( !blockLimit ) {
|
||||
elementName = e.getName();
|
||||
|
||||
// First editable element becomes a block limit, because it cannot be split.
|
||||
if ( e.getAttribute( 'contenteditable' ) == 'true' )
|
||||
blockLimit = e;
|
||||
// "Else" because element cannot be both - block and block levelimit.
|
||||
else if ( !block && pathBlockElements[ elementName ] )
|
||||
block = e;
|
||||
|
||||
if ( pathBlockLimitElements[ elementName ] ) {
|
||||
// End level DIV is considered as the block, if no block is available. (https://dev.ckeditor.com/ticket/525)
|
||||
// But it must NOT be the root element (checked above).
|
||||
if ( !block && elementName == 'div' && !checkHasBlock( e ) )
|
||||
block = e;
|
||||
else
|
||||
blockLimit = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while ( ( e = e.getParent() ) );
|
||||
|
||||
// Block limit defaults to root.
|
||||
if ( !blockLimit )
|
||||
blockLimit = root;
|
||||
|
||||
/**
|
||||
* First non-empty block element which:
|
||||
*
|
||||
* * is not a {@link CKEDITOR.dtd#$blockLimit},
|
||||
* * or is a `div` which does not contain block elements and is not a `root`.
|
||||
*
|
||||
* This means a first, splittable block in elements path.
|
||||
*
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element}
|
||||
*/
|
||||
this.block = block;
|
||||
|
||||
/**
|
||||
* See the {@link CKEDITOR.dtd#$blockLimit} description.
|
||||
*
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element}
|
||||
*/
|
||||
this.blockLimit = blockLimit;
|
||||
|
||||
/**
|
||||
* The root of the elements path - `root` argument passed to class constructor or a `body` element.
|
||||
*
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element}
|
||||
*/
|
||||
this.root = root;
|
||||
|
||||
/**
|
||||
* An array of elements (from `startNode` to `root`) in the path.
|
||||
*
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element[]}
|
||||
*/
|
||||
this.elements = elements;
|
||||
|
||||
/**
|
||||
* The last element of the elements path - `startNode` or its parent.
|
||||
*
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element} lastElement
|
||||
*/
|
||||
};
|
||||
|
||||
} )();
|
||||
|
||||
CKEDITOR.dom.elementPath.prototype = {
|
||||
/**
|
||||
* Compares this element path with another one.
|
||||
*
|
||||
* @param {CKEDITOR.dom.elementPath} otherPath The elementPath object to be
|
||||
* compared with this one.
|
||||
* @returns {Boolean} `true` if the paths are equal, containing the same
|
||||
* number of elements and the same elements in the same order.
|
||||
*/
|
||||
compare: function( otherPath ) {
|
||||
var thisElements = this.elements;
|
||||
var otherElements = otherPath && otherPath.elements;
|
||||
|
||||
if ( !otherElements || thisElements.length != otherElements.length )
|
||||
return false;
|
||||
|
||||
for ( var i = 0; i < thisElements.length; i++ ) {
|
||||
if ( !thisElements[ i ].equals( otherElements[ i ] ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Search the path elements that meets the specified criteria.
|
||||
*
|
||||
* @param {String/Array/Function/Object/CKEDITOR.dom.element} query The criteria that can be
|
||||
* either a tag name, list (array and object) of tag names, element or an node evaluator function.
|
||||
* @param {Boolean} [excludeRoot] Not taking path root element into consideration.
|
||||
* @param {Boolean} [fromTop] Search start from the topmost element instead of bottom.
|
||||
* @returns {CKEDITOR.dom.element} The first matched dom element or `null`.
|
||||
*/
|
||||
contains: function( query, excludeRoot, fromTop ) {
|
||||
var i = 0,
|
||||
evaluator;
|
||||
|
||||
if ( typeof query == 'string' )
|
||||
evaluator = function( node ) {
|
||||
return node.getName() == query;
|
||||
};
|
||||
if ( query instanceof CKEDITOR.dom.element )
|
||||
evaluator = function( node ) {
|
||||
return node.equals( query );
|
||||
};
|
||||
else if ( CKEDITOR.tools.isArray( query ) )
|
||||
evaluator = function( node ) {
|
||||
return CKEDITOR.tools.indexOf( query, node.getName() ) > -1;
|
||||
};
|
||||
else if ( typeof query == 'function' )
|
||||
evaluator = query;
|
||||
else if ( typeof query == 'object' )
|
||||
evaluator = function( node ) {
|
||||
return node.getName() in query;
|
||||
};
|
||||
|
||||
var elements = this.elements,
|
||||
length = elements.length;
|
||||
|
||||
if ( excludeRoot ) {
|
||||
if ( !fromTop ) {
|
||||
length -= 1;
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fromTop ) {
|
||||
elements = Array.prototype.slice.call( elements, 0 );
|
||||
elements.reverse();
|
||||
}
|
||||
|
||||
for ( ; i < length; i++ ) {
|
||||
if ( evaluator( elements[ i ] ) )
|
||||
return elements[ i ];
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether the elements path is the proper context for the specified
|
||||
* tag name in the DTD.
|
||||
*
|
||||
* @param {String} tag The tag name.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isContextFor: function( tag ) {
|
||||
var holder;
|
||||
|
||||
// Check for block context.
|
||||
if ( tag in CKEDITOR.dtd.$block ) {
|
||||
// Indeterminate elements which are not subjected to be splitted or surrounded must be checked first.
|
||||
var inter = this.contains( CKEDITOR.dtd.$intermediate );
|
||||
holder = inter || ( this.root.equals( this.block ) && this.block ) || this.blockLimit;
|
||||
return !!holder.getDtd()[ tag ];
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the text direction for this elements path.
|
||||
*
|
||||
* @returns {'ltr'/'rtl'}
|
||||
*/
|
||||
direction: function() {
|
||||
var directionNode = this.block || this.blockLimit || this.root;
|
||||
return directionNode.getDirection( 1 );
|
||||
}
|
||||
};
|
||||
238
Admin/plugins/ckeditor/core/dom/event.js
Normal file
238
Admin/plugins/ckeditor/core/dom/event.js
Normal file
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.event} class, which
|
||||
* represents the a native DOM event object.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a native DOM event object.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates an event class instance.
|
||||
* @param {Object} domEvent A native DOM event object.
|
||||
*/
|
||||
CKEDITOR.dom.event = function( domEvent ) {
|
||||
/**
|
||||
* The native DOM event object represented by this class instance.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
this.$ = domEvent;
|
||||
};
|
||||
|
||||
CKEDITOR.dom.event.prototype = {
|
||||
/**
|
||||
* Gets the key code associated to the event.
|
||||
*
|
||||
* alert( event.getKey() ); // '65' if 'a' has been pressed
|
||||
*
|
||||
* @returns {Number} The key code.
|
||||
*/
|
||||
getKey: function() {
|
||||
return this.$.keyCode || this.$.which;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a number represeting the combination of the keys pressed during the
|
||||
* event. It is the sum with the current key code and the {@link CKEDITOR#CTRL},
|
||||
* {@link CKEDITOR#SHIFT} and {@link CKEDITOR#ALT} constants.
|
||||
*
|
||||
* alert( event.getKeystroke() == 65 ); // 'a' key
|
||||
* alert( event.getKeystroke() == CKEDITOR.CTRL + 65 ); // CTRL + 'a' key
|
||||
* alert( event.getKeystroke() == CKEDITOR.CTRL + CKEDITOR.SHIFT + 65 ); // CTRL + SHIFT + 'a' key
|
||||
*
|
||||
* @returns {Number} The number representing the keys combination.
|
||||
*/
|
||||
getKeystroke: function() {
|
||||
var keystroke = this.getKey();
|
||||
|
||||
if ( this.$.ctrlKey || this.$.metaKey )
|
||||
keystroke += CKEDITOR.CTRL;
|
||||
|
||||
if ( this.$.shiftKey )
|
||||
keystroke += CKEDITOR.SHIFT;
|
||||
|
||||
if ( this.$.altKey )
|
||||
keystroke += CKEDITOR.ALT;
|
||||
|
||||
return keystroke;
|
||||
},
|
||||
|
||||
/**
|
||||
* Prevents the original behavior of the event to happen. It can optionally
|
||||
* stop propagating the event in the event chain.
|
||||
*
|
||||
* var element = CKEDITOR.document.getById( 'myElement' );
|
||||
* element.on( 'click', function( ev ) {
|
||||
* // The DOM event object is passed by the 'data' property.
|
||||
* var domEvent = ev.data;
|
||||
* // Prevent the click to chave any effect in the element.
|
||||
* domEvent.preventDefault();
|
||||
* } );
|
||||
*
|
||||
* @param {Boolean} [stopPropagation=false] Stop propagating this event in the
|
||||
* event chain.
|
||||
*/
|
||||
preventDefault: function( stopPropagation ) {
|
||||
var $ = this.$;
|
||||
if ( $.preventDefault )
|
||||
$.preventDefault();
|
||||
else
|
||||
$.returnValue = false;
|
||||
|
||||
if ( stopPropagation )
|
||||
this.stopPropagation();
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops this event propagation in the event chain.
|
||||
*/
|
||||
stopPropagation: function() {
|
||||
var $ = this.$;
|
||||
if ( $.stopPropagation )
|
||||
$.stopPropagation();
|
||||
else
|
||||
$.cancelBubble = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the DOM node where the event was targeted to.
|
||||
*
|
||||
* var element = CKEDITOR.document.getById( 'myElement' );
|
||||
* element.on( 'click', function( ev ) {
|
||||
* // The DOM event object is passed by the 'data' property.
|
||||
* var domEvent = ev.data;
|
||||
* // Add a CSS class to the event target.
|
||||
* domEvent.getTarget().addClass( 'clicked' );
|
||||
* } );
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node} The target DOM node.
|
||||
*/
|
||||
getTarget: function() {
|
||||
var rawNode = this.$.target || this.$.srcElement;
|
||||
return rawNode ? new CKEDITOR.dom.node( rawNode ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an integer value that indicates the current processing phase of an event.
|
||||
* For browsers that doesn't support event phase, {@link CKEDITOR#EVENT_PHASE_AT_TARGET} is always returned.
|
||||
*
|
||||
* @returns {Number} One of {@link CKEDITOR#EVENT_PHASE_CAPTURING},
|
||||
* {@link CKEDITOR#EVENT_PHASE_AT_TARGET}, or {@link CKEDITOR#EVENT_PHASE_BUBBLING}.
|
||||
*/
|
||||
getPhase: function() {
|
||||
return this.$.eventPhase || 2;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the coordinates of the mouse pointer relative to the top-left
|
||||
* corner of the document, in mouse related event.
|
||||
*
|
||||
* element.on( 'mousemouse', function( ev ) {
|
||||
* var pageOffset = ev.data.getPageOffset();
|
||||
* alert( pageOffset.x ); // page offset X
|
||||
* alert( pageOffset.y ); // page offset Y
|
||||
* } );
|
||||
*
|
||||
* @returns {Object} The object contains the position.
|
||||
* @returns {Number} return.x
|
||||
* @returns {Number} return.y
|
||||
*/
|
||||
getPageOffset: function() {
|
||||
var doc = this.getTarget().getDocument().$;
|
||||
var pageX = this.$.pageX || this.$.clientX + ( doc.documentElement.scrollLeft || doc.body.scrollLeft );
|
||||
var pageY = this.$.pageY || this.$.clientY + ( doc.documentElement.scrollTop || doc.body.scrollTop );
|
||||
return { x: pageX, y: pageY };
|
||||
}
|
||||
};
|
||||
|
||||
// For the followind constants, we need to go over the Unicode boundaries
|
||||
// (0x10FFFF) to avoid collision.
|
||||
|
||||
/**
|
||||
* CTRL key (0x110000).
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=0x110000]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.CTRL = 0x110000;
|
||||
|
||||
/**
|
||||
* SHIFT key (0x220000).
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=0x220000]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.SHIFT = 0x220000;
|
||||
|
||||
/**
|
||||
* ALT key (0x440000).
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=0x440000]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.ALT = 0x440000;
|
||||
|
||||
/**
|
||||
* Capturing phase.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.EVENT_PHASE_CAPTURING = 1;
|
||||
|
||||
/**
|
||||
* Event at target.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.EVENT_PHASE_AT_TARGET = 2;
|
||||
|
||||
/**
|
||||
* Bubbling phase.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=3]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.EVENT_PHASE_BUBBLING = 3;
|
||||
|
||||
/**
|
||||
* Integration with browser's "Go back" and "Go forward" buttons using Native History API.
|
||||
*
|
||||
* @since 4.17.0
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.HISTORY_NATIVE = 1;
|
||||
|
||||
/**
|
||||
* Integration with browser's "Go back" and "Go forward" buttons using hash-based navigation.
|
||||
*
|
||||
* @since 4.17.0
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.HISTORY_HASH = 2;
|
||||
|
||||
/**
|
||||
* Switch off integration with browser's "Go back" and "Go forward" buttons.
|
||||
*
|
||||
* @since 4.17.0
|
||||
* @readonly
|
||||
* @property {Number} [=0]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.HISTORY_OFF = 0;
|
||||
565
Admin/plugins/ckeditor/core/dom/iterator.js
Normal file
565
Admin/plugins/ckeditor/core/dom/iterator.js
Normal file
@@ -0,0 +1,565 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* File overview: DOM iterator which iterates over list items, lines and paragraphs.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Represents the iterator class. It can be used to iterate
|
||||
* over all elements (or even text nodes in case of {@link #enlargeBr} set to `false`)
|
||||
* which establish "paragraph-like" spaces within the passed range.
|
||||
*
|
||||
* // <h1>[foo</h1><p>bar]</p>
|
||||
* var iterator = range.createIterator();
|
||||
* iterator.getNextParagraph(); // h1 element
|
||||
* iterator.getNextParagraph(); // p element
|
||||
*
|
||||
* // <ul><li>[foo</li><li>bar]</li>
|
||||
* // With enforceRealBlocks set to false the iterator will return two list item elements.
|
||||
* // With enforceRealBlocks set to true the iterator will return two paragraphs and the DOM will be changed to:
|
||||
* // <ul><li><p>foo</p></li><li><p>bar</p></li>
|
||||
*
|
||||
* @class CKEDITOR.dom.iterator
|
||||
* @constructor Creates an iterator class instance.
|
||||
* @param {CKEDITOR.dom.range} range
|
||||
*/
|
||||
function iterator( range ) {
|
||||
if ( arguments.length < 1 )
|
||||
return;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.range}
|
||||
*/
|
||||
this.range = range;
|
||||
|
||||
/**
|
||||
* @property {Boolean} [forceBrBreak=false]
|
||||
*/
|
||||
this.forceBrBreak = 0;
|
||||
|
||||
// (https://dev.ckeditor.com/ticket/3730).
|
||||
/**
|
||||
* Whether to include `<br>` elements in the enlarged range. Should be
|
||||
* set to `false` when using the iterator in the {@link CKEDITOR#ENTER_BR} mode.
|
||||
*
|
||||
* @property {Boolean} [enlargeBr=true]
|
||||
*/
|
||||
this.enlargeBr = 1;
|
||||
|
||||
/**
|
||||
* Whether the iterator should create a transformable block
|
||||
* if the current one contains text and cannot be transformed.
|
||||
* For example new blocks will be established in elements like
|
||||
* `<li>` or `<td>`.
|
||||
*
|
||||
* @property {Boolean} [enforceRealBlocks=false]
|
||||
*/
|
||||
this.enforceRealBlocks = 0;
|
||||
|
||||
this._ || ( this._ = {} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Default iterator's filter. It is set only for nested iterators.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @readonly
|
||||
* @property {CKEDITOR.filter} filter
|
||||
*/
|
||||
|
||||
/**
|
||||
* Iterator's active filter. It is set by the {@link #getNextParagraph} method
|
||||
* when it enters a nested editable.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @readonly
|
||||
* @property {CKEDITOR.filter} activeFilter
|
||||
*/
|
||||
|
||||
var beginWhitespaceRegex = /^[\r\n\t ]+$/,
|
||||
// Ignore bookmark nodes.(https://dev.ckeditor.com/ticket/3783)
|
||||
bookmarkGuard = CKEDITOR.dom.walker.bookmark( false, true ),
|
||||
whitespacesGuard = CKEDITOR.dom.walker.whitespaces( true ),
|
||||
skipGuard = function( node ) {
|
||||
return bookmarkGuard( node ) && whitespacesGuard( node );
|
||||
},
|
||||
listItemNames = { dd: 1, dt: 1, li: 1 };
|
||||
|
||||
iterator.prototype = {
|
||||
/**
|
||||
* Returns the next paragraph-like element or `null` if the end of a range is reached.
|
||||
*
|
||||
* @param {String} [blockTag='p'] Name of a block element which will be established by
|
||||
* the iterator in block-less elements (see {@link #enforceRealBlocks}).
|
||||
*/
|
||||
getNextParagraph: function( blockTag ) {
|
||||
// The block element to be returned.
|
||||
var block;
|
||||
|
||||
// The range object used to identify the paragraph contents.
|
||||
var range;
|
||||
|
||||
// Indicats that the current element in the loop is the last one.
|
||||
var isLast;
|
||||
|
||||
// Instructs to cleanup remaining BRs.
|
||||
var removePreviousBr, removeLastBr;
|
||||
|
||||
blockTag = blockTag || 'p';
|
||||
|
||||
// We're iterating over nested editable.
|
||||
if ( this._.nestedEditable ) {
|
||||
// Get next block from nested iterator and returns it if was found.
|
||||
block = this._.nestedEditable.iterator.getNextParagraph( blockTag );
|
||||
if ( block ) {
|
||||
// Inherit activeFilter from the nested iterator.
|
||||
this.activeFilter = this._.nestedEditable.iterator.activeFilter;
|
||||
return block;
|
||||
}
|
||||
|
||||
// No block in nested iterator means that we reached the end of the nested editable.
|
||||
// Reset the active filter to the default filter (or undefined if this iterator didn't have it).
|
||||
this.activeFilter = this.filter;
|
||||
|
||||
// Try to find next nested editable or get back to parent (this) iterator.
|
||||
if ( startNestedEditableIterator( this, blockTag, this._.nestedEditable.container, this._.nestedEditable.remaining ) ) {
|
||||
// Inherit activeFilter from the nested iterator.
|
||||
this.activeFilter = this._.nestedEditable.iterator.activeFilter;
|
||||
return this._.nestedEditable.iterator.getNextParagraph( blockTag );
|
||||
} else {
|
||||
this._.nestedEditable = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Block-less range should be checked first.
|
||||
if ( !this.range.root.getDtd()[ blockTag ] )
|
||||
return null;
|
||||
|
||||
// This is the first iteration. Let's initialize it.
|
||||
if ( !this._.started )
|
||||
range = startIterator.call( this );
|
||||
|
||||
var currentNode = this._.nextNode,
|
||||
lastNode = this._.lastNode;
|
||||
|
||||
this._.nextNode = null;
|
||||
while ( currentNode ) {
|
||||
// closeRange indicates that a paragraph boundary has been found,
|
||||
// so the range can be closed.
|
||||
var closeRange = 0,
|
||||
parentPre = currentNode.hasAscendant( 'pre' );
|
||||
|
||||
// includeNode indicates that the current node is good to be part
|
||||
// of the range. By default, any non-element node is ok for it.
|
||||
var includeNode = ( currentNode.type != CKEDITOR.NODE_ELEMENT ),
|
||||
continueFromSibling = 0;
|
||||
|
||||
// If it is an element node, let's check if it can be part of the range.
|
||||
if ( !includeNode ) {
|
||||
var nodeName = currentNode.getName();
|
||||
|
||||
// Non-editable block was found - return it and move to processing
|
||||
// its nested editables if they exist.
|
||||
if ( CKEDITOR.dtd.$block[ nodeName ] && currentNode.getAttribute( 'contenteditable' ) == 'false' ) {
|
||||
block = currentNode;
|
||||
|
||||
// Setup iterator for first of nested editables.
|
||||
// If there's no editable, then algorithm will move to next element after current block.
|
||||
startNestedEditableIterator( this, blockTag, block );
|
||||
|
||||
// Gets us straight to the end of getParagraph() because block variable is set.
|
||||
break;
|
||||
} else if ( currentNode.isBlockBoundary( this.forceBrBreak && !parentPre && { br: 1 } ) ) {
|
||||
// <br> boundaries must be part of the range. It will
|
||||
// happen only if ForceBrBreak.
|
||||
if ( nodeName == 'br' )
|
||||
includeNode = 1;
|
||||
else if ( !range && !currentNode.getChildCount() && nodeName != 'hr' ) {
|
||||
// If we have found an empty block, and haven't started
|
||||
// the range yet, it means we must return this block.
|
||||
block = currentNode;
|
||||
isLast = currentNode.equals( lastNode );
|
||||
break;
|
||||
}
|
||||
|
||||
// The range must finish right before the boundary,
|
||||
// including possibly skipped empty spaces. (https://dev.ckeditor.com/ticket/1603)
|
||||
if ( range ) {
|
||||
range.setEndAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
|
||||
|
||||
// The found boundary must be set as the next one at this
|
||||
// point. (https://dev.ckeditor.com/ticket/1717)
|
||||
if ( nodeName != 'br' ) {
|
||||
this._.nextNode = currentNode;
|
||||
}
|
||||
}
|
||||
|
||||
closeRange = 1;
|
||||
} else {
|
||||
// If we have child nodes, let's check them.
|
||||
if ( currentNode.getFirst() ) {
|
||||
// If we don't have a range yet, let's start it.
|
||||
if ( !range ) {
|
||||
range = this.range.clone();
|
||||
range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
|
||||
}
|
||||
|
||||
currentNode = currentNode.getFirst();
|
||||
continue;
|
||||
}
|
||||
includeNode = 1;
|
||||
}
|
||||
} else if ( currentNode.type == CKEDITOR.NODE_TEXT ) {
|
||||
// Ignore normal whitespaces (i.e. not including or
|
||||
// other unicode whitespaces) before/after a block node.
|
||||
if ( beginWhitespaceRegex.test( currentNode.getText() ) )
|
||||
includeNode = 0;
|
||||
}
|
||||
|
||||
// The current node is good to be part of the range and we are
|
||||
// starting a new range, initialize it first.
|
||||
if ( includeNode && !range ) {
|
||||
range = this.range.clone();
|
||||
range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
|
||||
}
|
||||
|
||||
// The last node has been found.
|
||||
isLast = ( ( !closeRange || includeNode ) && currentNode.equals( lastNode ) );
|
||||
|
||||
// If we are in an element boundary, let's check if it is time
|
||||
// to close the range, otherwise we include the parent within it.
|
||||
if ( range && !closeRange ) {
|
||||
while ( !currentNode.getNext( skipGuard ) && !isLast ) {
|
||||
var parentNode = currentNode.getParent();
|
||||
|
||||
if ( parentNode.isBlockBoundary( this.forceBrBreak && !parentPre && { br: 1 } ) ) {
|
||||
closeRange = 1;
|
||||
includeNode = 0;
|
||||
isLast = isLast || ( parentNode.equals( lastNode ) );
|
||||
// Make sure range includes bookmarks at the end of the block. (https://dev.ckeditor.com/ticket/7359)
|
||||
range.setEndAt( parentNode, CKEDITOR.POSITION_BEFORE_END );
|
||||
break;
|
||||
}
|
||||
|
||||
currentNode = parentNode;
|
||||
includeNode = 1;
|
||||
isLast = ( currentNode.equals( lastNode ) );
|
||||
continueFromSibling = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Now finally include the node.
|
||||
if ( includeNode )
|
||||
range.setEndAt( currentNode, CKEDITOR.POSITION_AFTER_END );
|
||||
|
||||
currentNode = this._getNextSourceNode( currentNode, continueFromSibling, lastNode );
|
||||
isLast = !currentNode;
|
||||
|
||||
// We have found a block boundary. Let's close the range and move out of the
|
||||
// loop.
|
||||
if ( isLast || ( closeRange && range ) )
|
||||
break;
|
||||
}
|
||||
|
||||
// Now, based on the processed range, look for (or create) the block to be returned.
|
||||
if ( !block ) {
|
||||
// If no range has been found, this is the end.
|
||||
if ( !range ) {
|
||||
this._.docEndMarker && this._.docEndMarker.remove();
|
||||
this._.nextNode = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
var startPath = new CKEDITOR.dom.elementPath( range.startContainer, range.root );
|
||||
var startBlockLimit = startPath.blockLimit,
|
||||
checkLimits = { div: 1, th: 1, td: 1 };
|
||||
block = startPath.block;
|
||||
|
||||
if ( !block && startBlockLimit && !this.enforceRealBlocks && checkLimits[ startBlockLimit.getName() ] &&
|
||||
range.checkStartOfBlock() && range.checkEndOfBlock() && !startBlockLimit.equals( range.root ) ) {
|
||||
block = startBlockLimit;
|
||||
} else if ( !block || ( this.enforceRealBlocks && block.is( listItemNames ) ) ) {
|
||||
// Create the fixed block.
|
||||
block = this.range.document.createElement( blockTag );
|
||||
|
||||
// Move the contents of the temporary range to the fixed block.
|
||||
range.extractContents().appendTo( block );
|
||||
block.trim();
|
||||
|
||||
// Insert the fixed block into the DOM.
|
||||
range.insertNode( block );
|
||||
|
||||
removePreviousBr = removeLastBr = true;
|
||||
} else if ( block.getName() != 'li' ) {
|
||||
// If the range doesn't includes the entire contents of the
|
||||
// block, we must split it, isolating the range in a dedicated
|
||||
// block.
|
||||
if ( !range.checkStartOfBlock() || !range.checkEndOfBlock() ) {
|
||||
// The resulting block will be a clone of the current one.
|
||||
block = block.clone( false );
|
||||
|
||||
// Extract the range contents, moving it to the new block.
|
||||
range.extractContents().appendTo( block );
|
||||
block.trim();
|
||||
|
||||
// Split the block. At this point, the range will be in the
|
||||
// right position for our intents.
|
||||
var splitInfo = range.splitBlock();
|
||||
|
||||
removePreviousBr = !splitInfo.wasStartOfBlock;
|
||||
removeLastBr = !splitInfo.wasEndOfBlock;
|
||||
|
||||
// Insert the new block into the DOM.
|
||||
range.insertNode( block );
|
||||
}
|
||||
} else if ( !isLast ) {
|
||||
// LIs are returned as is, with all their children (due to the
|
||||
// nested lists). But, the next node is the node right after
|
||||
// the current range, which could be an <li> child (nested
|
||||
// lists) or the next sibling <li>.
|
||||
|
||||
this._.nextNode = ( block.equals( lastNode ) ? null : this._getNextSourceNode( range.getBoundaryNodes().endNode, 1, lastNode ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( removePreviousBr ) {
|
||||
var previousSibling = block.getPrevious();
|
||||
if ( previousSibling && previousSibling.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
if ( previousSibling.getName() == 'br' )
|
||||
previousSibling.remove();
|
||||
else if ( previousSibling.getLast() && previousSibling.getLast().$.nodeName.toLowerCase() == 'br' )
|
||||
previousSibling.getLast().remove();
|
||||
}
|
||||
}
|
||||
|
||||
if ( removeLastBr ) {
|
||||
var lastChild = block.getLast();
|
||||
if ( lastChild && lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.getName() == 'br' ) {
|
||||
// Remove br filler on browser which do not need it.
|
||||
if ( !CKEDITOR.env.needsBrFiller || lastChild.getPrevious( bookmarkGuard ) || lastChild.getNext( bookmarkGuard ) )
|
||||
lastChild.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Get a reference for the next element. This is important because the
|
||||
// above block can be removed or changed, so we can rely on it for the
|
||||
// next interation.
|
||||
if ( !this._.nextNode ) {
|
||||
this._.nextNode = ( isLast || block.equals( lastNode ) || !lastNode ) ? null : this._getNextSourceNode( block, 1, lastNode );
|
||||
}
|
||||
|
||||
return block;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the next element to check or `null` when the `lastNode` or the
|
||||
* {@link #range}'s {@link CKEDITOR.dom.range#root root} is reached. Bookmarks are skipped.
|
||||
*
|
||||
* @since 4.4.6
|
||||
* @private
|
||||
* @param {CKEDITOR.dom.node} node
|
||||
* @param {Boolean} startFromSibling
|
||||
* @param {CKEDITOR.dom.node} lastNode
|
||||
* @returns {CKEDITOR.dom.node}
|
||||
*/
|
||||
_getNextSourceNode: function( node, startFromSibling, lastNode ) {
|
||||
var rootNode = this.range.root,
|
||||
next;
|
||||
|
||||
// Here we are checking in guard function whether current element
|
||||
// reach lastNode(default behaviour) and root node to prevent against
|
||||
// getting out of editor instance root DOM object.
|
||||
// https://dev.ckeditor.com/ticket/12484
|
||||
function guardFunction( node ) {
|
||||
return !( node.equals( lastNode ) || node.equals( rootNode ) );
|
||||
}
|
||||
|
||||
next = node.getNextSourceNode( startFromSibling, null, guardFunction );
|
||||
while ( !bookmarkGuard( next ) ) {
|
||||
next = next.getNextSourceNode( startFromSibling, null, guardFunction );
|
||||
}
|
||||
return next;
|
||||
}
|
||||
};
|
||||
|
||||
// @context CKEDITOR.dom.iterator
|
||||
// @returns Collapsed range which will be reused when during furter processing.
|
||||
function startIterator() {
|
||||
var range = this.range.clone(),
|
||||
// Indicate at least one of the range boundaries is inside a preformat block.
|
||||
touchPre,
|
||||
|
||||
// (https://dev.ckeditor.com/ticket/12178)
|
||||
// Remember if following situation takes place:
|
||||
// * startAtInnerBoundary: <p>foo[</p>...
|
||||
// * endAtInnerBoundary: ...<p>]bar</p>
|
||||
// Because information about line break will be lost when shrinking range.
|
||||
// Note that we test only if path block exist, because we must properly shrink
|
||||
// range containing table and/or table cells.
|
||||
// Note: When range is collapsed there's no way it can be shrinked.
|
||||
// By checking if range is collapsed we also prevent https://dev.ckeditor.com/ticket/12308.
|
||||
startPath = range.startPath(),
|
||||
endPath = range.endPath(),
|
||||
startAtInnerBoundary = !range.collapsed && rangeAtInnerBlockBoundary( range, startPath.block ),
|
||||
endAtInnerBoundary = !range.collapsed && rangeAtInnerBlockBoundary( range, endPath.block, 1 );
|
||||
|
||||
// Shrink the range to exclude harmful "noises" (https://dev.ckeditor.com/ticket/4087, https://dev.ckeditor.com/ticket/4450, https://dev.ckeditor.com/ticket/5435).
|
||||
range.shrink( CKEDITOR.SHRINK_ELEMENT, true );
|
||||
|
||||
if ( startAtInnerBoundary )
|
||||
range.setStartAt( startPath.block, CKEDITOR.POSITION_BEFORE_END );
|
||||
if ( endAtInnerBoundary )
|
||||
range.setEndAt( endPath.block, CKEDITOR.POSITION_AFTER_START );
|
||||
|
||||
touchPre = range.endContainer.hasAscendant( 'pre', true ) || range.startContainer.hasAscendant( 'pre', true );
|
||||
|
||||
range.enlarge( this.forceBrBreak && !touchPre || !this.enlargeBr ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
|
||||
|
||||
if ( !range.collapsed ) {
|
||||
var walker = new CKEDITOR.dom.walker( range.clone() ),
|
||||
ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( true, true );
|
||||
// Avoid anchor inside bookmark inner text.
|
||||
walker.evaluator = ignoreBookmarkTextEvaluator;
|
||||
this._.nextNode = walker.next();
|
||||
// TODO: It's better to have walker.reset() used here.
|
||||
walker = new CKEDITOR.dom.walker( range.clone() );
|
||||
walker.evaluator = ignoreBookmarkTextEvaluator;
|
||||
var lastNode = walker.previous();
|
||||
this._.lastNode = lastNode.getNextSourceNode( true, null, range.root );
|
||||
|
||||
// We may have an empty text node at the end of block due to [3770].
|
||||
// If that node is the lastNode, it would cause our logic to leak to the
|
||||
// next block.(https://dev.ckeditor.com/ticket/3887)
|
||||
if ( this._.lastNode && this._.lastNode.type == CKEDITOR.NODE_TEXT && !CKEDITOR.tools.trim( this._.lastNode.getText() ) && this._.lastNode.getParent().isBlockBoundary() ) {
|
||||
var testRange = this.range.clone();
|
||||
testRange.moveToPosition( this._.lastNode, CKEDITOR.POSITION_AFTER_END );
|
||||
if ( testRange.checkEndOfBlock() ) {
|
||||
var path = new CKEDITOR.dom.elementPath( testRange.endContainer, testRange.root ),
|
||||
lastBlock = path.block || path.blockLimit;
|
||||
this._.lastNode = lastBlock.getNextSourceNode( true );
|
||||
}
|
||||
}
|
||||
|
||||
// The end of document or range.root was reached, so we need a marker node inside.
|
||||
if ( !this._.lastNode || !range.root.contains( this._.lastNode ) ) {
|
||||
this._.lastNode = this._.docEndMarker = range.document.createText( '' );
|
||||
this._.lastNode.insertAfter( lastNode );
|
||||
}
|
||||
|
||||
// Let's reuse this variable.
|
||||
range = null;
|
||||
}
|
||||
|
||||
this._.started = 1;
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
// Does a nested editables lookup inside editablesContainer.
|
||||
// If remainingEditables is set will lookup inside this array.
|
||||
// @param {CKEDITOR.dom.element} editablesContainer
|
||||
// @param {CKEDITOR.dom.element[]} [remainingEditables]
|
||||
function getNestedEditableIn( editablesContainer, remainingEditables ) {
|
||||
if ( remainingEditables == null )
|
||||
remainingEditables = findNestedEditables( editablesContainer );
|
||||
|
||||
var editable;
|
||||
|
||||
while ( ( editable = remainingEditables.shift() ) ) {
|
||||
if ( isIterableEditable( editable ) )
|
||||
return { element: editable, remaining: remainingEditables };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Checkes whether we can iterate over this editable.
|
||||
function isIterableEditable( editable ) {
|
||||
// Reject blockless editables.
|
||||
return editable.getDtd().p;
|
||||
}
|
||||
|
||||
// Finds nested editables within container. Does not return
|
||||
// editables nested in another editable (twice).
|
||||
function findNestedEditables( container ) {
|
||||
var editables = [];
|
||||
|
||||
container.forEach( function( element ) {
|
||||
if ( element.getAttribute( 'contenteditable' ) == 'true' ) {
|
||||
editables.push( element );
|
||||
return false; // Skip children.
|
||||
}
|
||||
}, CKEDITOR.NODE_ELEMENT, true );
|
||||
|
||||
return editables;
|
||||
}
|
||||
|
||||
// Looks for a first nested editable after previousEditable (if passed) and creates
|
||||
// nested iterator for it.
|
||||
function startNestedEditableIterator( parentIterator, blockTag, editablesContainer, remainingEditables ) {
|
||||
var editable = getNestedEditableIn( editablesContainer, remainingEditables );
|
||||
|
||||
if ( !editable )
|
||||
return 0;
|
||||
|
||||
var filter = CKEDITOR.filter.instances[ editable.element.data( 'cke-filter' ) ];
|
||||
|
||||
// If current editable has a filter and this filter does not allow for block tag,
|
||||
// search for next nested editable in remaining ones.
|
||||
if ( filter && !filter.check( blockTag ) )
|
||||
return startNestedEditableIterator( parentIterator, blockTag, editablesContainer, editable.remaining );
|
||||
|
||||
var range = new CKEDITOR.dom.range( editable.element );
|
||||
range.selectNodeContents( editable.element );
|
||||
|
||||
var iterator = range.createIterator();
|
||||
// This setting actually does not change anything in this case,
|
||||
// because entire range contents is selected, so there're no <br>s to be included.
|
||||
// But it seems right to copy it too.
|
||||
iterator.enlargeBr = parentIterator.enlargeBr;
|
||||
// Inherit configuration from parent iterator.
|
||||
iterator.enforceRealBlocks = parentIterator.enforceRealBlocks;
|
||||
// Set the activeFilter (which can be overriden when this iteator will start nested iterator)
|
||||
// and the default filter, which will make it possible to reset to
|
||||
// current iterator's activeFilter after leaving nested editable.
|
||||
iterator.activeFilter = iterator.filter = filter;
|
||||
|
||||
parentIterator._.nestedEditable = {
|
||||
element: editable.element,
|
||||
container: editablesContainer,
|
||||
remaining: editable.remaining,
|
||||
iterator: iterator
|
||||
};
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Checks whether range starts or ends at inner block boundary.
|
||||
// See usage comments to learn more.
|
||||
function rangeAtInnerBlockBoundary( range, block, checkEnd ) {
|
||||
if ( !block )
|
||||
return false;
|
||||
|
||||
var testRange = range.clone();
|
||||
testRange.collapse( !checkEnd );
|
||||
return testRange.checkBoundaryOfElement( block, checkEnd ? CKEDITOR.START : CKEDITOR.END );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link CKEDITOR.dom.iterator} instance for this range.
|
||||
*
|
||||
* @member CKEDITOR.dom.range
|
||||
* @returns {CKEDITOR.dom.iterator}
|
||||
*/
|
||||
CKEDITOR.dom.range.prototype.createIterator = function() {
|
||||
return new iterator( this );
|
||||
};
|
||||
} )();
|
||||
898
Admin/plugins/ckeditor/core/dom/node.js
Normal file
898
Admin/plugins/ckeditor/core/dom/node.js
Normal file
@@ -0,0 +1,898 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.node} class which is the base
|
||||
* class for classes that represent DOM nodes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for classes representing DOM nodes. This constructor may return
|
||||
* an instance of a class that inherits from this class, like
|
||||
* {@link CKEDITOR.dom.element} or {@link CKEDITOR.dom.text}.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.dom.domObject
|
||||
* @constructor Creates a node class instance.
|
||||
* @param {Object} domNode A native DOM node.
|
||||
* @see CKEDITOR.dom.element
|
||||
* @see CKEDITOR.dom.text
|
||||
*/
|
||||
CKEDITOR.dom.node = function( domNode ) {
|
||||
if ( domNode ) {
|
||||
var type =
|
||||
domNode.nodeType == CKEDITOR.NODE_DOCUMENT ? 'document' :
|
||||
domNode.nodeType == CKEDITOR.NODE_ELEMENT ? 'element' :
|
||||
domNode.nodeType == CKEDITOR.NODE_TEXT ? 'text' :
|
||||
domNode.nodeType == CKEDITOR.NODE_COMMENT ? 'comment' :
|
||||
domNode.nodeType == CKEDITOR.NODE_DOCUMENT_FRAGMENT ? 'documentFragment' :
|
||||
'domObject'; // Call the base constructor otherwise.
|
||||
|
||||
return new CKEDITOR.dom[ type ]( domNode );
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
CKEDITOR.dom.node.prototype = new CKEDITOR.dom.domObject();
|
||||
|
||||
/**
|
||||
* Element node type.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.NODE_ELEMENT = 1;
|
||||
|
||||
/**
|
||||
* Document node type.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=9]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.NODE_DOCUMENT = 9;
|
||||
|
||||
/**
|
||||
* Text node type.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=3]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.NODE_TEXT = 3;
|
||||
|
||||
/**
|
||||
* Comment node type.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=8]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.NODE_COMMENT = 8;
|
||||
|
||||
/**
|
||||
* Document fragment node type.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=11]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.NODE_DOCUMENT_FRAGMENT = 11;
|
||||
|
||||
/**
|
||||
* Indicates that positions of both nodes are identical (this is the same node). See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=0]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_IDENTICAL = 0;
|
||||
|
||||
/**
|
||||
* Indicates that nodes are in different (detached) trees. See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_DISCONNECTED = 1;
|
||||
|
||||
/**
|
||||
* Indicates that the context node follows the other node. See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_FOLLOWING = 2;
|
||||
|
||||
/**
|
||||
* Indicates that the context node precedes the other node. See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=4]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_PRECEDING = 4;
|
||||
|
||||
/**
|
||||
* Indicates that the context node is a descendant of the other node. See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=8]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_IS_CONTAINED = 8;
|
||||
|
||||
/**
|
||||
* Indicates that the context node contains the other node. See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=16]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_CONTAINS = 16;
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.node.prototype, {
|
||||
/**
|
||||
* Makes this node a child of another element.
|
||||
*
|
||||
* var p = new CKEDITOR.dom.element( 'p' );
|
||||
* var strong = new CKEDITOR.dom.element( 'strong' );
|
||||
* strong.appendTo( p );
|
||||
*
|
||||
* // Result: '<p><strong></strong></p>'.
|
||||
*
|
||||
* @param {CKEDITOR.dom.element} element The target element to which this node will be appended.
|
||||
* @returns {CKEDITOR.dom.element} The target element.
|
||||
*/
|
||||
appendTo: function( element, toStart ) {
|
||||
element.append( this, toStart );
|
||||
return element;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clones this node.
|
||||
*
|
||||
* **Note**: Values set by {#setCustomData} will not be available in the clone.
|
||||
*
|
||||
* @param {Boolean} [includeChildren=false] If `true` then all node's
|
||||
* children will be cloned recursively.
|
||||
* @param {Boolean} [cloneId=false] Whether ID attributes should be cloned, too.
|
||||
* @returns {CKEDITOR.dom.node} Clone of this node.
|
||||
*/
|
||||
clone: function( includeChildren, cloneId ) {
|
||||
var $clone = this.$.cloneNode( includeChildren );
|
||||
|
||||
// The "id" attribute should never be cloned to avoid duplication.
|
||||
removeIds( $clone );
|
||||
|
||||
var node = new CKEDITOR.dom.node( $clone );
|
||||
|
||||
// On IE8 we need to fixed HTML5 node name, see details below.
|
||||
if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 &&
|
||||
( this.type == CKEDITOR.NODE_ELEMENT || this.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT ) ) {
|
||||
renameNodes( node );
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
function removeIds( node ) {
|
||||
// Reset data-cke-expando only when has been cloned (IE and only for some types of objects).
|
||||
if ( node[ 'data-cke-expando' ] )
|
||||
node[ 'data-cke-expando' ] = false;
|
||||
|
||||
if ( node.nodeType != CKEDITOR.NODE_ELEMENT && node.nodeType != CKEDITOR.NODE_DOCUMENT_FRAGMENT )
|
||||
return;
|
||||
|
||||
if ( !cloneId && node.nodeType == CKEDITOR.NODE_ELEMENT )
|
||||
node.removeAttribute( 'id', false );
|
||||
|
||||
if ( includeChildren ) {
|
||||
var childs = node.childNodes;
|
||||
for ( var i = 0; i < childs.length; i++ )
|
||||
removeIds( childs[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
// IE8 rename HTML5 nodes by adding `:` at the begging of the tag name when the node is cloned,
|
||||
// so `<figure>` will be `<:figure>` after 'cloneNode'. We need to fix it (https://dev.ckeditor.com/ticket/13101).
|
||||
function renameNodes( node ) {
|
||||
if ( node.type != CKEDITOR.NODE_ELEMENT && node.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT )
|
||||
return;
|
||||
|
||||
if ( node.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT ) {
|
||||
var name = node.getName();
|
||||
if ( name[ 0 ] == ':' ) {
|
||||
node.renameNode( name.substring( 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( includeChildren ) {
|
||||
for ( var i = 0; i < node.getChildCount(); i++ )
|
||||
renameNodes( node.getChild( i ) );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the node is preceded by any sibling.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasPrevious: function() {
|
||||
return !!this.$.previousSibling;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the node is succeeded by any sibling.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasNext: function() {
|
||||
return !!this.$.nextSibling;
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts this element after a node.
|
||||
*
|
||||
* var em = new CKEDITOR.dom.element( 'em' );
|
||||
* var strong = new CKEDITOR.dom.element( 'strong' );
|
||||
* strong.insertAfter( em );
|
||||
*
|
||||
* // Result: '<em></em><strong></strong>'
|
||||
*
|
||||
* @param {CKEDITOR.dom.node} node The node that will precede this element.
|
||||
* @returns {CKEDITOR.dom.node} The node preceding this one after insertion.
|
||||
*/
|
||||
insertAfter: function( node ) {
|
||||
node.$.parentNode.insertBefore( this.$, node.$.nextSibling );
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts this element before a node.
|
||||
*
|
||||
* var em = new CKEDITOR.dom.element( 'em' );
|
||||
* var strong = new CKEDITOR.dom.element( 'strong' );
|
||||
* strong.insertBefore( em );
|
||||
*
|
||||
* // result: '<strong></strong><em></em>'
|
||||
*
|
||||
* @param {CKEDITOR.dom.node} node The node that will succeed this element.
|
||||
* @returns {CKEDITOR.dom.node} The node being inserted.
|
||||
*/
|
||||
insertBefore: function( node ) {
|
||||
node.$.parentNode.insertBefore( this.$, node.$ );
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts a node before this node.
|
||||
*
|
||||
* var em = new CKEDITOR.dom.element( 'em' );
|
||||
* var strong = new CKEDITOR.dom.element( 'strong' );
|
||||
* strong.insertBeforeMe( em );
|
||||
*
|
||||
* // result: '<em></em><strong></strong>'
|
||||
*
|
||||
* @param {CKEDITOR.dom.node} node The node that will preceed this element.
|
||||
* @returns {CKEDITOR.dom.node} The node being inserted.
|
||||
*/
|
||||
insertBeforeMe: function( node ) {
|
||||
this.$.parentNode.insertBefore( node.$, this.$ );
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves a uniquely identifiable tree address for this node.
|
||||
* The tree address returned is an array of integers, with each integer
|
||||
* indicating a child index of a DOM node, starting from
|
||||
* `document.documentElement`.
|
||||
*
|
||||
* For example, assuming `<body>` is the second child
|
||||
* of `<html>` (`<head>` being the first),
|
||||
* and we would like to address the third child under the
|
||||
* fourth child of `<body>`, the tree address returned would be:
|
||||
* `[1, 3, 2]`.
|
||||
*
|
||||
* The tree address cannot be used for finding back the DOM tree node once
|
||||
* the DOM tree structure has been modified.
|
||||
*
|
||||
* @param {Boolean} [normalized=false] See {@link #getIndex}.
|
||||
* @returns {Array} The address.
|
||||
*/
|
||||
getAddress: function( normalized ) {
|
||||
var address = [];
|
||||
var $documentElement = this.getDocument().$.documentElement;
|
||||
var node = this;
|
||||
|
||||
while ( node && node != $documentElement ) {
|
||||
var parentNode = node.getParent();
|
||||
|
||||
if ( parentNode ) {
|
||||
// Get the node index. For performance, call getIndex
|
||||
// directly, instead of creating a new node object.
|
||||
address.unshift( this.getIndex.call( node, normalized ) );
|
||||
}
|
||||
|
||||
node = parentNode;
|
||||
}
|
||||
|
||||
return address;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the document containing this element.
|
||||
*
|
||||
* var element = CKEDITOR.document.getById( 'example' );
|
||||
* alert( element.getDocument().equals( CKEDITOR.document ) ); // true
|
||||
*
|
||||
* @returns {CKEDITOR.dom.document} The document.
|
||||
*/
|
||||
getDocument: function() {
|
||||
return new CKEDITOR.dom.document( this.$.ownerDocument || this.$.parentNode.ownerDocument );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the index of a node in an array of its `parent.childNodes`.
|
||||
* Returns `-1` if a node does not have a parent or when the `normalized` argument is set to `true`
|
||||
* and the text node is empty and will be removed during the normalization.
|
||||
*
|
||||
* Let us assume having the following `childNodes` array:
|
||||
*
|
||||
* [ emptyText, element1, text, text, element2, emptyText2 ]
|
||||
*
|
||||
* emptyText.getIndex() // 0
|
||||
* emptyText.getIndex( true ) // -1
|
||||
* element1.getIndex(); // 1
|
||||
* element1.getIndex( true ); // 0
|
||||
* element2.getIndex(); // 4
|
||||
* element2.getIndex( true ); // 2
|
||||
* emptyText2.getIndex(); // 5
|
||||
* emptyText2.getIndex( true ); // -1
|
||||
*
|
||||
* @param {Boolean} normalized When `true`, adjacent text nodes are merged and empty text nodes are removed.
|
||||
* @returns {Number} Index of a node or `-1` if a node does not have a parent or is removed during the normalization.
|
||||
*/
|
||||
getIndex: function( normalized ) {
|
||||
// Attention: getAddress depends on this.$
|
||||
// getIndex is called on a plain object: { $ : node }
|
||||
|
||||
var current = this,
|
||||
index = -1,
|
||||
isNormalizing;
|
||||
|
||||
if ( !this.getParent() )
|
||||
return -1;
|
||||
|
||||
// The idea is - all empty text nodes will be virtually merged into their adjacent text nodes.
|
||||
// If an empty text node does not have an adjacent non-empty text node we can return -1 straight away,
|
||||
// because it and all its sibling text nodes will be merged into an empty text node and then totally ignored.
|
||||
if ( normalized && current.type == CKEDITOR.NODE_TEXT && current.isEmpty() ) {
|
||||
var adjacent = getAdjacentNonEmptyTextNode( current ) || getAdjacentNonEmptyTextNode( current, true );
|
||||
|
||||
if ( !adjacent )
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
// Bypass blank node and adjacent text nodes.
|
||||
if ( normalized && !current.equals( this ) && current.type == CKEDITOR.NODE_TEXT && ( isNormalizing || current.isEmpty() ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
index++;
|
||||
isNormalizing = current.type == CKEDITOR.NODE_TEXT;
|
||||
}
|
||||
while ( ( current = current.getPrevious() ) );
|
||||
|
||||
return index;
|
||||
|
||||
function getAdjacentNonEmptyTextNode( node, lookForward ) {
|
||||
var sibling = lookForward ? node.getNext() : node.getPrevious();
|
||||
|
||||
if ( !sibling || sibling.type != CKEDITOR.NODE_TEXT ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If found a non-empty text node, then return it.
|
||||
// If not, then continue search.
|
||||
return sibling.isEmpty() ? getAdjacentNonEmptyTextNode( sibling, lookForward ) : sibling;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
getNextSourceNode: function( startFromSibling, nodeType, guard ) {
|
||||
// If "guard" is a node, transform it in a function.
|
||||
if ( guard && !guard.call ) {
|
||||
var guardNode = guard;
|
||||
guard = function( node ) {
|
||||
return !node.equals( guardNode );
|
||||
};
|
||||
}
|
||||
|
||||
var node = ( !startFromSibling && this.getFirst && this.getFirst() ),
|
||||
parent;
|
||||
|
||||
// Guarding when we're skipping the current element( no children or 'startFromSibling' ).
|
||||
// send the 'moving out' signal even we don't actually dive into.
|
||||
if ( !node ) {
|
||||
if ( this.type == CKEDITOR.NODE_ELEMENT && guard && guard( this, true ) === false )
|
||||
return null;
|
||||
node = this.getNext();
|
||||
}
|
||||
|
||||
while ( !node && ( parent = ( parent || this ).getParent() ) ) {
|
||||
// The guard check sends the "true" paramenter to indicate that
|
||||
// we are moving "out" of the element.
|
||||
if ( guard && guard( parent, true ) === false )
|
||||
return null;
|
||||
|
||||
node = parent.getNext();
|
||||
}
|
||||
|
||||
if ( !node )
|
||||
return null;
|
||||
|
||||
if ( guard && guard( node ) === false )
|
||||
return null;
|
||||
|
||||
if ( nodeType && nodeType != node.type )
|
||||
return node.getNextSourceNode( false, nodeType, guard );
|
||||
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
getPreviousSourceNode: function( startFromSibling, nodeType, guard ) {
|
||||
if ( guard && !guard.call ) {
|
||||
var guardNode = guard;
|
||||
guard = function( node ) {
|
||||
return !node.equals( guardNode );
|
||||
};
|
||||
}
|
||||
|
||||
var node = ( !startFromSibling && this.getLast && this.getLast() ),
|
||||
parent;
|
||||
|
||||
// Guarding when we're skipping the current element( no children or 'startFromSibling' ).
|
||||
// send the 'moving out' signal even we don't actually dive into.
|
||||
if ( !node ) {
|
||||
if ( this.type == CKEDITOR.NODE_ELEMENT && guard && guard( this, true ) === false )
|
||||
return null;
|
||||
node = this.getPrevious();
|
||||
}
|
||||
|
||||
while ( !node && ( parent = ( parent || this ).getParent() ) ) {
|
||||
// The guard check sends the "true" paramenter to indicate that
|
||||
// we are moving "out" of the element.
|
||||
if ( guard && guard( parent, true ) === false )
|
||||
return null;
|
||||
|
||||
node = parent.getPrevious();
|
||||
}
|
||||
|
||||
if ( !node )
|
||||
return null;
|
||||
|
||||
if ( guard && guard( node ) === false )
|
||||
return null;
|
||||
|
||||
if ( nodeType && node.type != nodeType )
|
||||
return node.getPreviousSourceNode( false, nodeType, guard );
|
||||
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the node that preceeds this element in its parent's child list.
|
||||
*
|
||||
* var element = CKEDITOR.dom.element.createFromHtml( '<div><i>prev</i><b>Example</b></div>' );
|
||||
* var first = element.getLast().getPrev();
|
||||
* alert( first.getName() ); // 'i'
|
||||
*
|
||||
* @param {Function} [evaluator] Filtering the result node.
|
||||
* @returns {CKEDITOR.dom.node} The previous node or null if not available.
|
||||
*/
|
||||
getPrevious: function( evaluator ) {
|
||||
var previous = this.$,
|
||||
retval;
|
||||
do {
|
||||
previous = previous.previousSibling;
|
||||
|
||||
// Avoid returning the doc type node.
|
||||
// http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-412266927
|
||||
retval = previous && previous.nodeType != 10 && new CKEDITOR.dom.node( previous );
|
||||
}
|
||||
while ( retval && evaluator && !evaluator( retval ) );
|
||||
return retval;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the node that follows this element in its parent's child list.
|
||||
*
|
||||
* var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b><i>next</i></div>' );
|
||||
* var last = element.getFirst().getNext();
|
||||
* alert( last.getName() ); // 'i'
|
||||
*
|
||||
* @param {Function} [evaluator] Filtering the result node.
|
||||
* @returns {CKEDITOR.dom.node} The next node or null if not available.
|
||||
*/
|
||||
getNext: function( evaluator ) {
|
||||
var next = this.$,
|
||||
retval;
|
||||
do {
|
||||
next = next.nextSibling;
|
||||
retval = next && new CKEDITOR.dom.node( next );
|
||||
}
|
||||
while ( retval && evaluator && !evaluator( retval ) );
|
||||
return retval;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the parent element for this node.
|
||||
*
|
||||
* var node = editor.document.getBody().getFirst();
|
||||
* var parent = node.getParent();
|
||||
* alert( parent.getName() ); // 'body'
|
||||
*
|
||||
* @param {Boolean} [allowFragmentParent=false] Consider also parent node that is of
|
||||
* fragment type {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
|
||||
* @returns {CKEDITOR.dom.element} The parent element.
|
||||
*/
|
||||
getParent: function( allowFragmentParent ) {
|
||||
var parent = this.$.parentNode;
|
||||
return ( parent && ( parent.nodeType == CKEDITOR.NODE_ELEMENT || allowFragmentParent && parent.nodeType == CKEDITOR.NODE_DOCUMENT_FRAGMENT ) ) ? new CKEDITOR.dom.node( parent ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an array containing node parents and the node itself. By default nodes are in _descending_ order.
|
||||
*
|
||||
* // Assuming that body has paragraph as the first child.
|
||||
* var node = editor.document.getBody().getFirst();
|
||||
* var parents = node.getParents();
|
||||
* alert( parents[ 0 ].getName() + ',' + parents[ 2 ].getName() ); // 'html,p'
|
||||
*
|
||||
* @param {Boolean} [closerFirst=false] Determines the order of returned nodes.
|
||||
* @returns {Array} Returns an array of {@link CKEDITOR.dom.node}.
|
||||
*/
|
||||
getParents: function( closerFirst ) {
|
||||
var node = this;
|
||||
var parents = [];
|
||||
|
||||
do {
|
||||
parents[ closerFirst ? 'push' : 'unshift' ]( node );
|
||||
}
|
||||
while ( ( node = node.getParent() ) );
|
||||
|
||||
return parents;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
getCommonAncestor: function( node ) {
|
||||
if ( node.equals( this ) )
|
||||
return this;
|
||||
|
||||
if ( node.contains && node.contains( this ) )
|
||||
return node;
|
||||
|
||||
var start = this.contains ? this : this.getParent();
|
||||
|
||||
do {
|
||||
if ( start.contains( node ) ) return start;
|
||||
}
|
||||
while ( ( start = start.getParent() ) );
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines the position relation between this node and the given {@link CKEDITOR.dom.node} in the document.
|
||||
* This node can be preceding ({@link CKEDITOR#POSITION_PRECEDING}) or following ({@link CKEDITOR#POSITION_FOLLOWING})
|
||||
* the given node. This node can also contain ({@link CKEDITOR#POSITION_CONTAINS}) or be contained by
|
||||
* ({@link CKEDITOR#POSITION_IS_CONTAINED}) the given node. The function returns a bitmask of constants
|
||||
* listed above or {@link CKEDITOR#POSITION_IDENTICAL} if the given node is the same as this node.
|
||||
*
|
||||
* @param {CKEDITOR.dom.node} otherNode A node to check relation with.
|
||||
* @returns {Number} Position relation between this node and given node.
|
||||
*/
|
||||
getPosition: function( otherNode ) {
|
||||
var $ = this.$;
|
||||
var $other = otherNode.$;
|
||||
|
||||
if ( $.compareDocumentPosition )
|
||||
return $.compareDocumentPosition( $other );
|
||||
|
||||
// IE and Safari have no support for compareDocumentPosition.
|
||||
|
||||
if ( $ == $other )
|
||||
return CKEDITOR.POSITION_IDENTICAL;
|
||||
|
||||
// Only element nodes support contains and sourceIndex.
|
||||
if ( this.type == CKEDITOR.NODE_ELEMENT && otherNode.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
if ( $.contains ) {
|
||||
if ( $.contains( $other ) )
|
||||
return CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING;
|
||||
|
||||
if ( $other.contains( $ ) )
|
||||
return CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
|
||||
}
|
||||
|
||||
if ( 'sourceIndex' in $ )
|
||||
return ( $.sourceIndex < 0 || $other.sourceIndex < 0 ) ? CKEDITOR.POSITION_DISCONNECTED : ( $.sourceIndex < $other.sourceIndex ) ? CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING;
|
||||
|
||||
}
|
||||
|
||||
// For nodes that don't support compareDocumentPosition, contains
|
||||
// or sourceIndex, their "address" is compared.
|
||||
|
||||
var addressOfThis = this.getAddress(),
|
||||
addressOfOther = otherNode.getAddress(),
|
||||
minLevel = Math.min( addressOfThis.length, addressOfOther.length );
|
||||
|
||||
// Determinate preceding/following relationship.
|
||||
for ( var i = 0; i < minLevel; i++ ) {
|
||||
if ( addressOfThis[ i ] != addressOfOther[ i ] ) {
|
||||
return addressOfThis[ i ] < addressOfOther[ i ] ? CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING;
|
||||
}
|
||||
}
|
||||
|
||||
// Determinate contains/contained relationship.
|
||||
return ( addressOfThis.length < addressOfOther.length ) ? CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the closest ancestor node of this node, specified by its name or using an evaluator function.
|
||||
*
|
||||
* // Suppose we have the following HTML structure:
|
||||
* // <div id="outer"><div id="inner"><p><b>Some text</b></p></div></div>
|
||||
* // If node == <b>
|
||||
* ascendant = node.getAscendant( 'div' ); // ascendant == <div id="inner">
|
||||
* ascendant = node.getAscendant( 'b' ); // ascendant == null
|
||||
* ascendant = node.getAscendant( 'b', true ); // ascendant == <b>
|
||||
* ascendant = node.getAscendant( { div:1, p:1 } ); // Searches for the first 'div' or 'p': ascendant == <div id="inner">
|
||||
*
|
||||
* // Using custom evaluator:
|
||||
* ascendant = node.getAscendant( function( el ) {
|
||||
* return el.getId() == 'inner';
|
||||
* } );
|
||||
* // ascendant == <div id="inner">
|
||||
*
|
||||
* @since 3.6.1
|
||||
* @param {String/Function/Object} query The name of the ancestor node to search or
|
||||
* an object with the node names to search for or an evaluator function.
|
||||
* @param {Boolean} [includeSelf] Whether to include the current
|
||||
* node in the search.
|
||||
* @returns {CKEDITOR.dom.node} The located ancestor node or `null` if not found.
|
||||
*/
|
||||
getAscendant: function( query, includeSelf ) {
|
||||
var $ = this.$,
|
||||
evaluator,
|
||||
isCustomEvaluator;
|
||||
|
||||
if ( !includeSelf ) {
|
||||
$ = $.parentNode;
|
||||
}
|
||||
|
||||
// Custom checker provided in an argument.
|
||||
if ( typeof query == 'function' ) {
|
||||
isCustomEvaluator = true;
|
||||
evaluator = query;
|
||||
} else {
|
||||
// Predefined tag name checker.
|
||||
isCustomEvaluator = false;
|
||||
evaluator = function( $ ) {
|
||||
var name = ( typeof $.nodeName == 'string' ? $.nodeName.toLowerCase() : '' );
|
||||
|
||||
return ( typeof query == 'string' ? name == query : name in query );
|
||||
};
|
||||
}
|
||||
|
||||
while ( $ ) {
|
||||
// For user provided checker we use CKEDITOR.dom.node.
|
||||
if ( evaluator( isCustomEvaluator ? new CKEDITOR.dom.node( $ ) : $ ) ) {
|
||||
return new CKEDITOR.dom.node( $ );
|
||||
}
|
||||
|
||||
try {
|
||||
$ = $.parentNode;
|
||||
} catch ( e ) {
|
||||
$ = null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
hasAscendant: function( name, includeSelf ) {
|
||||
var $ = this.$;
|
||||
|
||||
if ( !includeSelf )
|
||||
$ = $.parentNode;
|
||||
|
||||
while ( $ ) {
|
||||
if ( $.nodeName && $.nodeName.toLowerCase() == name )
|
||||
return true;
|
||||
|
||||
$ = $.parentNode;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
move: function( target, toStart ) {
|
||||
target.append( this.remove(), toStart );
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes this node from the document DOM.
|
||||
*
|
||||
* var element = CKEDITOR.document.getById( 'MyElement' );
|
||||
* element.remove();
|
||||
*
|
||||
* @param {Boolean} [preserveChildren=false] Indicates that the children
|
||||
* elements must remain in the document, removing only the outer tags.
|
||||
*/
|
||||
remove: function( preserveChildren ) {
|
||||
var $ = this.$;
|
||||
var parent = $.parentNode;
|
||||
|
||||
if ( parent ) {
|
||||
if ( preserveChildren ) {
|
||||
// Move all children before the node.
|
||||
for ( var child;
|
||||
( child = $.firstChild ); ) {
|
||||
parent.insertBefore( $.removeChild( child ), $ );
|
||||
}
|
||||
}
|
||||
|
||||
parent.removeChild( $ );
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
replace: function( nodeToReplace ) {
|
||||
this.insertBefore( nodeToReplace );
|
||||
nodeToReplace.remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
trim: function() {
|
||||
this.ltrim();
|
||||
this.rtrim();
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
ltrim: function() {
|
||||
var child;
|
||||
while ( this.getFirst && ( child = this.getFirst() ) ) {
|
||||
if ( child.type == CKEDITOR.NODE_TEXT ) {
|
||||
var trimmed = CKEDITOR.tools.ltrim( child.getText() ),
|
||||
originalLength = child.getLength();
|
||||
|
||||
if ( !trimmed ) {
|
||||
child.remove();
|
||||
continue;
|
||||
} else if ( trimmed.length < originalLength ) {
|
||||
child.split( originalLength - trimmed.length );
|
||||
|
||||
// IE BUG: child.remove() may raise JavaScript errors here. (https://dev.ckeditor.com/ticket/81)
|
||||
this.$.removeChild( this.$.firstChild );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
rtrim: function() {
|
||||
var child;
|
||||
while ( this.getLast && ( child = this.getLast() ) ) {
|
||||
if ( child.type == CKEDITOR.NODE_TEXT ) {
|
||||
var trimmed = CKEDITOR.tools.rtrim( child.getText() ),
|
||||
originalLength = child.getLength();
|
||||
|
||||
if ( !trimmed ) {
|
||||
child.remove();
|
||||
continue;
|
||||
} else if ( trimmed.length < originalLength ) {
|
||||
child.split( trimmed.length );
|
||||
|
||||
// IE BUG: child.getNext().remove() may raise JavaScript errors here.
|
||||
// (https://dev.ckeditor.com/ticket/81)
|
||||
this.$.lastChild.parentNode.removeChild( this.$.lastChild );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( CKEDITOR.env.needsBrFiller ) {
|
||||
child = this.$.lastChild;
|
||||
|
||||
if ( child && child.type == 1 && child.nodeName.toLowerCase() == 'br' ) {
|
||||
// Use "eChildNode.parentNode" instead of "node" to avoid IE bug (https://dev.ckeditor.com/ticket/324).
|
||||
child.parentNode.removeChild( child );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if this node is read-only (should not be changed).
|
||||
*
|
||||
* // For the following HTML:
|
||||
* // <b>foo</b><div contenteditable="false"><i>bar</i></div>
|
||||
*
|
||||
* elB.isReadOnly(); // -> false
|
||||
* foo.isReadOnly(); // -> false
|
||||
* elDiv.isReadOnly(); // -> true
|
||||
* elI.isReadOnly(); // -> true
|
||||
*
|
||||
* This method works in two modes depending on browser support for the `element.isContentEditable` property and
|
||||
* the value of the `checkOnlyAttributes` parameter. The `element.isContentEditable` check is faster, but it is known
|
||||
* to malfunction in hidden or detached nodes. Additionally, when processing some detached DOM tree you may want to imitate
|
||||
* that this happens inside an editable container (like it would happen inside the {@link CKEDITOR.editable}). To do so,
|
||||
* you can temporarily attach this tree to an element with the `data-cke-editable` attribute and use the
|
||||
* `checkOnlyAttributes` mode.
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @param {Boolean} [checkOnlyAttributes=false] If `true`, only attributes will be checked, native methods will not
|
||||
* be used. This parameter needs to be `true` to check hidden or detached elements. Introduced in 4.5.0.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isReadOnly: function( checkOnlyAttributes ) {
|
||||
var element = this;
|
||||
if ( this.type != CKEDITOR.NODE_ELEMENT )
|
||||
element = this.getParent();
|
||||
|
||||
// Prevent Edge crash (https://dev.ckeditor.com/ticket/13609, https://dev.ckeditor.com/ticket/13919).
|
||||
if ( CKEDITOR.env.edge && element && element.is( 'textarea', 'input' ) ) {
|
||||
checkOnlyAttributes = true;
|
||||
}
|
||||
|
||||
if ( !checkOnlyAttributes && element && typeof element.$.isContentEditable != 'undefined' ) {
|
||||
return !( element.$.isContentEditable || element.data( 'cke-editable' ) );
|
||||
}
|
||||
else {
|
||||
// Degrade for old browsers which don't support "isContentEditable", e.g. FF3
|
||||
|
||||
while ( element ) {
|
||||
if ( element.data( 'cke-editable' ) ) {
|
||||
return false;
|
||||
} else if ( element.hasAttribute( 'contenteditable' ) ) {
|
||||
return element.getAttribute( 'contenteditable' ) == 'false';
|
||||
}
|
||||
|
||||
element = element.getParent();
|
||||
}
|
||||
|
||||
// Reached the root of DOM tree, no editable found.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} );
|
||||
54
Admin/plugins/ckeditor/core/dom/nodelist.js
Normal file
54
Admin/plugins/ckeditor/core/dom/nodelist.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a list of {@link CKEDITOR.dom.node} objects.
|
||||
* It is a wrapper for a native nodes list.
|
||||
*
|
||||
* var nodeList = CKEDITOR.document.getBody().getChildren();
|
||||
* alert( nodeList.count() ); // number [0;N]
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a document class instance.
|
||||
* @param {Object} nativeList
|
||||
*/
|
||||
CKEDITOR.dom.nodeList = function( nativeList ) {
|
||||
this.$ = nativeList;
|
||||
};
|
||||
|
||||
CKEDITOR.dom.nodeList.prototype = {
|
||||
/**
|
||||
* Gets the count of nodes in this list.
|
||||
*
|
||||
* @returns {Number}
|
||||
*/
|
||||
count: function() {
|
||||
return this.$.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the node from the list.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node}
|
||||
*/
|
||||
getItem: function( index ) {
|
||||
if ( index < 0 || index >= this.$.length )
|
||||
return null;
|
||||
|
||||
var $node = this.$[ index ];
|
||||
return $node ? new CKEDITOR.dom.node( $node ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a node list as an array.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node[]}
|
||||
*/
|
||||
toArray: function() {
|
||||
return CKEDITOR.tools.array.map( this.$, function( nativeEl ) {
|
||||
return new CKEDITOR.dom.node( nativeEl );
|
||||
} );
|
||||
}
|
||||
};
|
||||
3417
Admin/plugins/ckeditor/core/dom/range.js
Normal file
3417
Admin/plugins/ckeditor/core/dom/range.js
Normal file
File diff suppressed because it is too large
Load Diff
199
Admin/plugins/ckeditor/core/dom/rangelist.js
Normal file
199
Admin/plugins/ckeditor/core/dom/rangelist.js
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Represents a list os CKEDITOR.dom.range objects, which can be easily
|
||||
* iterated sequentially.
|
||||
*
|
||||
* @class
|
||||
* @extends Array
|
||||
* @constructor Creates a rangeList class instance.
|
||||
* @param {CKEDITOR.dom.range/CKEDITOR.dom.range[]} [ranges] The ranges contained on this list.
|
||||
* Note that, if an array of ranges is specified, the range sequence
|
||||
* should match its DOM order. This class will not help to sort them.
|
||||
*/
|
||||
CKEDITOR.dom.rangeList = function( ranges ) {
|
||||
if ( ranges instanceof CKEDITOR.dom.rangeList )
|
||||
return ranges;
|
||||
|
||||
if ( !ranges )
|
||||
ranges = [];
|
||||
else if ( ranges instanceof CKEDITOR.dom.range )
|
||||
ranges = [ ranges ];
|
||||
|
||||
return CKEDITOR.tools.extend( ranges, mixins );
|
||||
};
|
||||
|
||||
var mixins = {
|
||||
/**
|
||||
* Creates an instance of the rangeList iterator, it should be used
|
||||
* only when the ranges processing could be DOM intrusive, which
|
||||
* means it may pollute and break other ranges in this list.
|
||||
* Otherwise, it's enough to just iterate over this array in a for loop.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.rangeListIterator}
|
||||
*/
|
||||
createIterator: function() {
|
||||
var rangeList = this,
|
||||
bookmark = CKEDITOR.dom.walker.bookmark(),
|
||||
bookmarks = [],
|
||||
current;
|
||||
|
||||
return {
|
||||
/**
|
||||
* Retrieves the next range in the list.
|
||||
*
|
||||
* @member CKEDITOR.dom.rangeListIterator
|
||||
* @param {Boolean} [mergeConsequent=false] Whether join two adjacent
|
||||
* ranges into single, e.g. consequent table cells.
|
||||
*/
|
||||
getNextRange: function( mergeConsequent ) {
|
||||
current = current === undefined ? 0 : current + 1;
|
||||
|
||||
var range = rangeList[ current ];
|
||||
|
||||
// Multiple ranges might be mangled by each other.
|
||||
if ( range && rangeList.length > 1 ) {
|
||||
// Bookmarking all other ranges on the first iteration,
|
||||
// the range correctness after it doesn't matter since we'll
|
||||
// restore them before the next iteration.
|
||||
if ( !current ) {
|
||||
// Make sure bookmark correctness by reverse processing.
|
||||
for ( var i = rangeList.length - 1; i >= 0; i-- )
|
||||
bookmarks.unshift( rangeList[ i ].createBookmark( true ) );
|
||||
}
|
||||
|
||||
if ( mergeConsequent ) {
|
||||
// Figure out how many ranges should be merged.
|
||||
var mergeCount = 0;
|
||||
while ( rangeList[ current + mergeCount + 1 ] ) {
|
||||
var doc = range.document,
|
||||
found = 0,
|
||||
left = doc.getById( bookmarks[ mergeCount ].endNode ),
|
||||
right = doc.getById( bookmarks[ mergeCount + 1 ].startNode ),
|
||||
next;
|
||||
|
||||
// Check subsequent range.
|
||||
while ( 1 ) {
|
||||
next = left.getNextSourceNode( false );
|
||||
if ( !right.equals( next ) ) {
|
||||
// This could be yet another bookmark or
|
||||
// walking across block boundaries.
|
||||
if ( bookmark( next ) || ( next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() ) ) {
|
||||
left = next;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
found = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !found )
|
||||
break;
|
||||
|
||||
mergeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
range.moveToBookmark( bookmarks.shift() );
|
||||
|
||||
// Merge ranges finally after moving to bookmarks.
|
||||
while ( mergeCount-- ) {
|
||||
next = rangeList[ ++current ];
|
||||
next.moveToBookmark( bookmarks.shift() );
|
||||
range.setEnd( next.endContainer, next.endOffset );
|
||||
}
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Create bookmarks for all ranges. See {@link CKEDITOR.dom.range#createBookmark}.
|
||||
*
|
||||
* @param {Boolean} [serializable=false] See {@link CKEDITOR.dom.range#createBookmark}.
|
||||
* @returns {Array} Array of bookmarks.
|
||||
*/
|
||||
createBookmarks: function( serializable ) {
|
||||
var retval = [],
|
||||
bookmark;
|
||||
for ( var i = 0; i < this.length; i++ ) {
|
||||
retval.push( bookmark = this[ i ].createBookmark( serializable, true ) );
|
||||
|
||||
// Updating the container & offset values for ranges
|
||||
// that have been touched.
|
||||
for ( var j = i + 1; j < this.length; j++ ) {
|
||||
this[ j ] = updateDirtyRange( bookmark, this[ j ] );
|
||||
this[ j ] = updateDirtyRange( bookmark, this[ j ], true );
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create "unobtrusive" bookmarks for all ranges. See {@link CKEDITOR.dom.range#createBookmark2}.
|
||||
*
|
||||
* @param {Boolean} [normalized=false] See {@link CKEDITOR.dom.range#createBookmark2}.
|
||||
* @returns {Array} Array of bookmarks.
|
||||
*/
|
||||
createBookmarks2: function( normalized ) {
|
||||
var bookmarks = [];
|
||||
|
||||
for ( var i = 0; i < this.length; i++ )
|
||||
bookmarks.push( this[ i ].createBookmark2( normalized ) );
|
||||
|
||||
return bookmarks;
|
||||
},
|
||||
|
||||
/**
|
||||
* Move each range in the list to the position specified by a list of bookmarks.
|
||||
*
|
||||
* @param {Array} bookmarks The list of bookmarks, each one matching a range in the list.
|
||||
*/
|
||||
moveToBookmarks: function( bookmarks ) {
|
||||
for ( var i = 0; i < this.length; i++ )
|
||||
this[ i ].moveToBookmark( bookmarks[ i ] );
|
||||
}
|
||||
};
|
||||
|
||||
// Update the specified range which has been mangled by previous insertion of
|
||||
// range bookmark nodes.(https://dev.ckeditor.com/ticket/3256)
|
||||
function updateDirtyRange( bookmark, dirtyRange, checkEnd ) {
|
||||
var serializable = bookmark.serializable,
|
||||
container = dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ],
|
||||
offset = checkEnd ? 'endOffset' : 'startOffset';
|
||||
|
||||
var bookmarkStart = serializable ? dirtyRange.document.getById( bookmark.startNode ) : bookmark.startNode;
|
||||
|
||||
var bookmarkEnd = serializable ? dirtyRange.document.getById( bookmark.endNode ) : bookmark.endNode;
|
||||
|
||||
if ( container.equals( bookmarkStart.getPrevious() ) ) {
|
||||
dirtyRange.startOffset = dirtyRange.startOffset - container.getLength() - bookmarkEnd.getPrevious().getLength();
|
||||
container = bookmarkEnd.getNext();
|
||||
} else if ( container.equals( bookmarkEnd.getPrevious() ) ) {
|
||||
dirtyRange.startOffset = dirtyRange.startOffset - container.getLength();
|
||||
container = bookmarkEnd.getNext();
|
||||
}
|
||||
|
||||
container.equals( bookmarkStart.getParent() ) && dirtyRange[ offset ]++;
|
||||
container.equals( bookmarkEnd.getParent() ) && dirtyRange[ offset ]++;
|
||||
|
||||
// Update and return this range.
|
||||
dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ] = container;
|
||||
return dirtyRange;
|
||||
}
|
||||
} )();
|
||||
|
||||
/**
|
||||
* (Virtual Class) Do not call this constructor. This class is not really part
|
||||
* of the API. It just describes the return type of {@link CKEDITOR.dom.rangeList#createIterator}.
|
||||
*
|
||||
* @class CKEDITOR.dom.rangeListIterator
|
||||
*/
|
||||
74
Admin/plugins/ckeditor/core/dom/rect.js
Normal file
74
Admin/plugins/ckeditor/core/dom/rect.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.dom.rect} class
|
||||
* that contains the definition of the element's DOM rectangle. This file is for
|
||||
* documentation purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Virtual class that illustrates the {@link CKEDITOR.dom.element} DOM rectangle (dimensions and coordinates
|
||||
* of the area that the element occupies on the page).
|
||||
*
|
||||
* @class CKEDITOR.dom.rect
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's offset from the viewport's top edge.
|
||||
*
|
||||
* @property {Number} top
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's bottom edge offset from the viewport's top edge.
|
||||
*
|
||||
* This value is the same as the {@link CKEDITOR.dom.rect#top} value plus the {@link CKEDITOR.dom.rect#height} value.
|
||||
*
|
||||
* @property {Number} bottom
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's offset from the viewport's left edge.
|
||||
*
|
||||
* @property {Number} left
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's right edge offset from the viewport's left edge.
|
||||
*
|
||||
* This value is the same as the {@link CKEDITOR.dom.rect#left} value plus the {@link CKEDITOR.dom.rect#width} value.
|
||||
*
|
||||
* @property {Number} right
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's height.
|
||||
*
|
||||
* @property {Number} height
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's width.
|
||||
*
|
||||
* @property {Number} width
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's offset from the viewport's left edge.
|
||||
*
|
||||
* This property is not available in Internet Explorer or Edge.
|
||||
*
|
||||
* @property {Number} x
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's offset from the viewport's top edge.
|
||||
*
|
||||
* This property is not available in Internet Explorer or Edge.
|
||||
*
|
||||
* @property {Number} y
|
||||
*/
|
||||
154
Admin/plugins/ckeditor/core/dom/text.js
Normal file
154
Admin/plugins/ckeditor/core/dom/text.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.text} class, which represents
|
||||
* a DOM text node.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a DOM text node.
|
||||
*
|
||||
* var nativeNode = document.createTextNode( 'Example' );
|
||||
* var text = new CKEDITOR.dom.text( nativeNode );
|
||||
*
|
||||
* var text = new CKEDITOR.dom.text( 'Example' );
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.dom.node
|
||||
* @constructor Creates a text class instance.
|
||||
* @param {Object/String} text A native DOM text node or a string containing
|
||||
* the text to use to create a new text node.
|
||||
* @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
|
||||
* the node in case of new node creation. Defaults to the current document.
|
||||
*/
|
||||
CKEDITOR.dom.text = function( text, ownerDocument ) {
|
||||
if ( typeof text == 'string' )
|
||||
text = ( ownerDocument ? ownerDocument.$ : document ).createTextNode( text );
|
||||
|
||||
// Theoretically, we should call the base constructor here
|
||||
// (not CKEDITOR.dom.node though). But, IE doesn't support expando
|
||||
// properties on text node, so the features provided by domObject will not
|
||||
// work for text nodes (which is not a big issue for us).
|
||||
//
|
||||
// CKEDITOR.dom.domObject.call( this, element );
|
||||
|
||||
this.$ = text;
|
||||
};
|
||||
|
||||
CKEDITOR.dom.text.prototype = new CKEDITOR.dom.node();
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.text.prototype, {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_TEXT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_TEXT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_TEXT,
|
||||
|
||||
/**
|
||||
* Gets length of node's value.
|
||||
*
|
||||
* @returns {Number}
|
||||
*/
|
||||
getLength: function() {
|
||||
return this.$.nodeValue.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets node's value.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
getText: function() {
|
||||
return this.$.nodeValue;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets node's value.
|
||||
*
|
||||
* @param {String} text
|
||||
*/
|
||||
setText: function( text ) {
|
||||
this.$.nodeValue = text;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks whether a node is empty or is a
|
||||
* {@link CKEDITOR.dom.selection#FILLING_CHAR_SEQUENCE FILLING_CHAR_SEQUENCE} string.
|
||||
*
|
||||
* @since 4.13.0
|
||||
* @param {Boolean} [ignoreWhiteSpace] Specifies whether the content that consists of only whitespace characters
|
||||
* should be treated as an empty one.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isEmpty: function( ignoreWhiteSpace ) {
|
||||
var text = this.getText();
|
||||
|
||||
if ( ignoreWhiteSpace ) {
|
||||
text = CKEDITOR.tools.trim( text );
|
||||
}
|
||||
|
||||
return !text || text === CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE;
|
||||
},
|
||||
|
||||
/**
|
||||
* Breaks this text node into two nodes at the specified offset,
|
||||
* keeping both in the tree as siblings. This node then only contains
|
||||
* all the content up to the offset point. A new text node, which is
|
||||
* inserted as the next sibling of this node, contains all the content
|
||||
* at and after the offset point. When the offset is equal to the
|
||||
* length of this node, the new node has no data.
|
||||
*
|
||||
* @param {Number} The position at which to split, starting from zero.
|
||||
* @returns {CKEDITOR.dom.text} The new text node.
|
||||
*/
|
||||
split: function( offset ) {
|
||||
|
||||
// Saved the children count and text length beforehand.
|
||||
var parent = this.$.parentNode,
|
||||
count = parent.childNodes.length,
|
||||
length = this.getLength();
|
||||
|
||||
var doc = this.getDocument();
|
||||
var retval = new CKEDITOR.dom.text( this.$.splitText( offset ), doc );
|
||||
|
||||
if ( parent.childNodes.length == count ) {
|
||||
// If the offset is after the last char, IE creates the text node
|
||||
// on split, but don't include it into the DOM. So, we have to do
|
||||
// that manually here.
|
||||
if ( offset >= length ) {
|
||||
retval = doc.createText( '' );
|
||||
retval.insertAfter( this );
|
||||
} else {
|
||||
// IE BUG: IE8+ does not update the childNodes array in DOM after splitText(),
|
||||
// we need to make some DOM changes to make it update. (https://dev.ckeditor.com/ticket/3436)
|
||||
var workaround = doc.createText( '' );
|
||||
workaround.insertAfter( retval );
|
||||
workaround.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts characters from indexA up to but not including `indexB`.
|
||||
*
|
||||
* @param {Number} indexA An integer between `0` and one less than the
|
||||
* length of the text.
|
||||
* @param {Number} [indexB] An integer between `0` and the length of the
|
||||
* string. If omitted, extracts characters to the end of the text.
|
||||
*/
|
||||
substring: function( indexA, indexB ) {
|
||||
// We need the following check due to a Firefox bug
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=458886
|
||||
if ( typeof indexB != 'number' )
|
||||
return this.$.nodeValue.substr( indexA );
|
||||
else
|
||||
return this.$.nodeValue.substring( indexA, indexB );
|
||||
}
|
||||
} );
|
||||
652
Admin/plugins/ckeditor/core/dom/walker.js
Normal file
652
Admin/plugins/ckeditor/core/dom/walker.js
Normal file
@@ -0,0 +1,652 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
( function() {
|
||||
// This function is to be called under a "walker" instance scope.
|
||||
function iterate( rtl, breakOnFalse ) {
|
||||
var range = this.range;
|
||||
|
||||
// Return null if we have reached the end.
|
||||
if ( this._.end )
|
||||
return null;
|
||||
|
||||
// This is the first call. Initialize it.
|
||||
if ( !this._.start ) {
|
||||
this._.start = 1;
|
||||
|
||||
// A collapsed range must return null at first call.
|
||||
if ( range.collapsed ) {
|
||||
this.end();
|
||||
return null;
|
||||
}
|
||||
|
||||
// Move outside of text node edges.
|
||||
range.optimize();
|
||||
}
|
||||
|
||||
var node,
|
||||
startCt = range.startContainer,
|
||||
endCt = range.endContainer,
|
||||
startOffset = range.startOffset,
|
||||
endOffset = range.endOffset,
|
||||
guard,
|
||||
userGuard = this.guard,
|
||||
type = this.type,
|
||||
getSourceNodeFn = ( rtl ? 'getPreviousSourceNode' : 'getNextSourceNode' );
|
||||
|
||||
// Create the LTR guard function, if necessary.
|
||||
if ( !rtl && !this._.guardLTR ) {
|
||||
// The node that stops walker from moving up.
|
||||
var limitLTR = endCt.type == CKEDITOR.NODE_ELEMENT ? endCt : endCt.getParent();
|
||||
|
||||
// The node that stops the walker from going to next.
|
||||
var blockerLTR = endCt.type == CKEDITOR.NODE_ELEMENT ? endCt.getChild( endOffset ) : endCt.getNext();
|
||||
|
||||
this._.guardLTR = function( node, movingOut ) {
|
||||
return ( ( !movingOut || !limitLTR.equals( node ) ) && ( !blockerLTR || !node.equals( blockerLTR ) ) && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || !node.equals( range.root ) ) );
|
||||
};
|
||||
}
|
||||
|
||||
// Create the RTL guard function, if necessary.
|
||||
if ( rtl && !this._.guardRTL ) {
|
||||
// The node that stops walker from moving up.
|
||||
var limitRTL = startCt.type == CKEDITOR.NODE_ELEMENT ? startCt : startCt.getParent();
|
||||
|
||||
// The node that stops the walker from going to next.
|
||||
var blockerRTL = startCt.type == CKEDITOR.NODE_ELEMENT ? startOffset ? startCt.getChild( startOffset - 1 ) : null : startCt.getPrevious();
|
||||
|
||||
this._.guardRTL = function( node, movingOut ) {
|
||||
return ( ( !movingOut || !limitRTL.equals( node ) ) && ( !blockerRTL || !node.equals( blockerRTL ) ) && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || !node.equals( range.root ) ) );
|
||||
};
|
||||
}
|
||||
|
||||
// Define which guard function to use.
|
||||
var stopGuard = rtl ? this._.guardRTL : this._.guardLTR;
|
||||
|
||||
// Make the user defined guard function participate in the process,
|
||||
// otherwise simply use the boundary guard.
|
||||
if ( userGuard ) {
|
||||
guard = function( node, movingOut ) {
|
||||
if ( stopGuard( node, movingOut ) === false )
|
||||
return false;
|
||||
|
||||
return userGuard( node, movingOut );
|
||||
};
|
||||
} else {
|
||||
guard = stopGuard;
|
||||
}
|
||||
|
||||
if ( this.current )
|
||||
node = this.current[ getSourceNodeFn ]( false, type, guard );
|
||||
else {
|
||||
// Get the first node to be returned.
|
||||
if ( rtl ) {
|
||||
node = endCt;
|
||||
|
||||
if ( node.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
if ( endOffset > 0 )
|
||||
node = node.getChild( endOffset - 1 );
|
||||
else
|
||||
node = ( guard( node, true ) === false ) ? null : node.getPreviousSourceNode( true, type, guard );
|
||||
}
|
||||
} else {
|
||||
node = startCt;
|
||||
|
||||
if ( node.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
if ( !( node = node.getChild( startOffset ) ) )
|
||||
node = ( guard( startCt, true ) === false ) ? null : startCt.getNextSourceNode( true, type, guard );
|
||||
}
|
||||
}
|
||||
|
||||
if ( node && guard( node ) === false )
|
||||
node = null;
|
||||
}
|
||||
|
||||
while ( node && !this._.end ) {
|
||||
this.current = node;
|
||||
|
||||
if ( !this.evaluator || this.evaluator( node ) !== false ) {
|
||||
if ( !breakOnFalse )
|
||||
return node;
|
||||
} else if ( breakOnFalse && this.evaluator ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
node = node[ getSourceNodeFn ]( false, type, guard );
|
||||
}
|
||||
|
||||
this.end();
|
||||
return this.current = null;
|
||||
}
|
||||
|
||||
function iterateToLast( rtl ) {
|
||||
var node,
|
||||
last = null;
|
||||
|
||||
while ( ( node = iterate.call( this, rtl ) ) )
|
||||
last = node;
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class to "walk" the DOM inside range boundaries. If the
|
||||
* range starts or ends in the middle of the text node, this node will
|
||||
* be included as a whole. Outside changes to the range may break the walker.
|
||||
*
|
||||
* The walker may return nodes that are not totally included in the
|
||||
* range boundaries. Let us take the following range representation,
|
||||
* where the square brackets indicate the boundaries:
|
||||
*
|
||||
* [<p>Some <b>sample] text</b>
|
||||
*
|
||||
* While walking forward into the above range, the following nodes are
|
||||
* returned: `<p>`, `"Some "`, `<b>` and `"sample"`. Going
|
||||
* backwards instead we have: `"sample"` and `"Some "`. So note that the
|
||||
* walker always returns nodes when "entering" them, but not when
|
||||
* "leaving" them. The {@link #guard} function is instead called both when
|
||||
* entering and when leaving nodes.
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
CKEDITOR.dom.walker = CKEDITOR.tools.createClass( {
|
||||
/**
|
||||
* Creates a walker class instance.
|
||||
*
|
||||
* @constructor
|
||||
* @param {CKEDITOR.dom.range} range The range within which to walk.
|
||||
*/
|
||||
$: function( range ) {
|
||||
this.range = range;
|
||||
|
||||
/**
|
||||
* A function executed for every matched node to check whether
|
||||
* it is to be considered in the walk or not. If not provided, all
|
||||
* matched nodes are considered good.
|
||||
*
|
||||
* If the function returns `false`, the node is ignored.
|
||||
*
|
||||
* @property {Function} evaluator
|
||||
*/
|
||||
// this.evaluator = null;
|
||||
|
||||
/**
|
||||
* A function executed for every node the walk passes by to check
|
||||
* whether the walk is to be finished. It is called both when
|
||||
* entering and when exiting nodes, as well as for the matched nodes.
|
||||
*
|
||||
* If this function returns `false`, the walking ends and no more
|
||||
* nodes are evaluated.
|
||||
|
||||
* @property {Function} guard
|
||||
*/
|
||||
// this.guard = null;
|
||||
|
||||
/** @private */
|
||||
this._ = {};
|
||||
},
|
||||
|
||||
// statics :
|
||||
// {
|
||||
// /* Creates a CKEDITOR.dom.walker instance to walk inside DOM boundaries set by nodes.
|
||||
// * @param {CKEDITOR.dom.node} startNode The node from which the walk
|
||||
// * will start.
|
||||
// * @param {CKEDITOR.dom.node} [endNode] The last node to be considered
|
||||
// * in the walk. No more nodes are retrieved after touching or
|
||||
// * passing it. If not provided, the walker stops at the
|
||||
// * <body> closing boundary.
|
||||
// * @returns {CKEDITOR.dom.walker} A DOM walker for the nodes between the
|
||||
// * provided nodes.
|
||||
// */
|
||||
// createOnNodes : function( startNode, endNode, startInclusive, endInclusive )
|
||||
// {
|
||||
// var range = new CKEDITOR.dom.range();
|
||||
// if ( startNode )
|
||||
// range.setStartAt( startNode, startInclusive ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_END ) ;
|
||||
// else
|
||||
// range.setStartAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_AFTER_START ) ;
|
||||
//
|
||||
// if ( endNode )
|
||||
// range.setEndAt( endNode, endInclusive ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START ) ;
|
||||
// else
|
||||
// range.setEndAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_BEFORE_END ) ;
|
||||
//
|
||||
// return new CKEDITOR.dom.walker( range );
|
||||
// }
|
||||
// },
|
||||
//
|
||||
proto: {
|
||||
/**
|
||||
* Stops walking. No more nodes are retrieved if this function is called.
|
||||
*/
|
||||
end: function() {
|
||||
this._.end = 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the next node (on the right).
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node} The next node or `null` if no more
|
||||
* nodes are available.
|
||||
*/
|
||||
next: function() {
|
||||
return iterate.call( this );
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the previous node (on the left).
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node} The previous node or `null` if no more
|
||||
* nodes are available.
|
||||
*/
|
||||
previous: function() {
|
||||
return iterate.call( this, 1 );
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks all nodes on the right, executing the evaluation function.
|
||||
*
|
||||
* @returns {Boolean} `false` if the evaluator function returned
|
||||
* `false` for any of the matched nodes. Otherwise `true`.
|
||||
*/
|
||||
checkForward: function() {
|
||||
return iterate.call( this, 0, 1 ) !== false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check all nodes on the left, executing the evaluation function.
|
||||
*
|
||||
* @returns {Boolean} `false` if the evaluator function returned
|
||||
* `false` for any of the matched nodes. Otherwise `true`.
|
||||
*/
|
||||
checkBackward: function() {
|
||||
return iterate.call( this, 1, 1 ) !== false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes a full walk forward (to the right), until no more nodes
|
||||
* are available, returning the last valid node.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node} The last node on the right or `null`
|
||||
* if no valid nodes are available.
|
||||
*/
|
||||
lastForward: function() {
|
||||
return iterateToLast.call( this );
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes a full walk backwards (to the left), until no more nodes
|
||||
* are available, returning the last valid node.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node} The last node on the left or `null`
|
||||
* if no valid nodes are available.
|
||||
*/
|
||||
lastBackward: function() {
|
||||
return iterateToLast.call( this, 1 );
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets the walker.
|
||||
*/
|
||||
reset: function() {
|
||||
delete this.current;
|
||||
this._ = {};
|
||||
}
|
||||
|
||||
}
|
||||
} );
|
||||
|
||||
// Anything whose display computed style is block, list-item, table,
|
||||
// table-row-group, table-header-group, table-footer-group, table-row,
|
||||
// table-column-group, table-column, table-cell, table-caption, or whose node
|
||||
// name is hr, br (when enterMode is br only) is a block boundary.
|
||||
var blockBoundaryDisplayMatch = {
|
||||
block: 1, 'list-item': 1, table: 1, 'table-row-group': 1,
|
||||
'table-header-group': 1, 'table-footer-group': 1, 'table-row': 1, 'table-column-group': 1,
|
||||
'table-column': 1, 'table-cell': 1, 'table-caption': 1
|
||||
},
|
||||
outOfFlowPositions = { absolute: 1, fixed: 1 };
|
||||
|
||||
/**
|
||||
* Checks whether an element is displayed as a block.
|
||||
*
|
||||
* @member CKEDITOR.dom.element
|
||||
* @param [customNodeNames] Custom list of nodes which will extend
|
||||
* the default {@link CKEDITOR.dtd#$block} list.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
CKEDITOR.dom.element.prototype.isBlockBoundary = function( customNodeNames ) {
|
||||
// Whether element is in normal page flow. Floated or positioned elements are out of page flow.
|
||||
// Don't consider floated or positioned formatting as block boundary, fall back to dtd check in that case. (https://dev.ckeditor.com/ticket/6297)
|
||||
var inPageFlow = this.getComputedStyle( 'float' ) == 'none' && !( this.getComputedStyle( 'position' ) in outOfFlowPositions );
|
||||
|
||||
if ( inPageFlow && blockBoundaryDisplayMatch[ this.getComputedStyle( 'display' ) ] )
|
||||
return true;
|
||||
|
||||
// Either in $block or in customNodeNames if defined.
|
||||
return !!( this.is( CKEDITOR.dtd.$block ) || customNodeNames && this.is( customNodeNames ) );
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is a block boundary.
|
||||
* See {@link CKEDITOR.dom.element#isBlockBoundary}.
|
||||
*
|
||||
* @static
|
||||
* @param customNodeNames
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.blockBoundary = function( customNodeNames ) {
|
||||
return function( node ) {
|
||||
return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary( customNodeNames ) );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @todo
|
||||
*/
|
||||
CKEDITOR.dom.walker.listItemBoundary = function() {
|
||||
return this.blockBoundary( { br: 1 } );
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is a bookmark node or the bookmark node
|
||||
* inner content.
|
||||
*
|
||||
* @static
|
||||
* @param {Boolean} [contentOnly=false] Whether only test against the text content of
|
||||
* a bookmark node instead of the element itself (default).
|
||||
* @param {Boolean} [isReject=false] Whether to return `false` for the bookmark
|
||||
* node instead of `true` (default).
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.bookmark = function( contentOnly, isReject ) {
|
||||
function isBookmarkNode( node ) {
|
||||
return ( node && node.getName && node.getName() == 'span' && node.data( 'cke-bookmark' ) );
|
||||
}
|
||||
|
||||
return function( node ) {
|
||||
var isBookmark, parent;
|
||||
// Is bookmark inner text node?
|
||||
isBookmark = ( node && node.type != CKEDITOR.NODE_ELEMENT && ( parent = node.getParent() ) && isBookmarkNode( parent ) );
|
||||
// Is bookmark node?
|
||||
isBookmark = contentOnly ? isBookmark : isBookmark || isBookmarkNode( node );
|
||||
return !!( isReject ^ isBookmark );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is a text node containing only whitespace characters.
|
||||
*
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false]
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.whitespaces = function( isReject ) {
|
||||
return function( node ) {
|
||||
var isWhitespace;
|
||||
if ( node && node.type == CKEDITOR.NODE_TEXT ) {
|
||||
// Whitespace, as well as the Filling Char Sequence text node used in Webkit. (https://dev.ckeditor.com/ticket/9384, https://dev.ckeditor.com/ticket/13816)
|
||||
isWhitespace = !CKEDITOR.tools.trim( node.getText() ) ||
|
||||
CKEDITOR.env.webkit && node.getText() == CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE;
|
||||
}
|
||||
|
||||
return !!( isReject ^ isWhitespace );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is invisible in the WYSIWYG mode.
|
||||
*
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false]
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.invisible = function( isReject ) {
|
||||
var whitespace = CKEDITOR.dom.walker.whitespaces(),
|
||||
// https://dev.ckeditor.com/ticket/12221 (Chrome) plus https://dev.ckeditor.com/ticket/11111 (Safari).
|
||||
offsetWidth0 = CKEDITOR.env.webkit ? 1 : 0;
|
||||
|
||||
return function( node ) {
|
||||
var invisible;
|
||||
|
||||
if ( whitespace( node ) )
|
||||
invisible = 1;
|
||||
else {
|
||||
// Visibility should be checked on element.
|
||||
if ( node.type == CKEDITOR.NODE_TEXT )
|
||||
node = node.getParent();
|
||||
|
||||
// Nodes that take no spaces in wysiwyg:
|
||||
// 1. White-spaces but not including NBSP.
|
||||
// 2. Empty inline elements, e.g. <b></b>.
|
||||
// 3. <br> elements (bogus, surrounded by text) (https://dev.ckeditor.com/ticket/12423).
|
||||
invisible = node.$.offsetWidth <= offsetWidth0;
|
||||
}
|
||||
|
||||
return !!( isReject ^ invisible );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node type is equal to the passed one.
|
||||
*
|
||||
* @static
|
||||
* @param {Number} type
|
||||
* @param {Boolean} [isReject=false]
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.nodeType = function( type, isReject ) {
|
||||
return function( node ) {
|
||||
return !!( isReject ^ ( node.type == type ) );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is a bogus (filler) node from
|
||||
* `contenteditable` element's point of view.
|
||||
*
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false]
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.bogus = function( isReject ) {
|
||||
function nonEmpty( node ) {
|
||||
return !isWhitespaces( node ) && !isBookmark( node );
|
||||
}
|
||||
|
||||
return function( node ) {
|
||||
var isBogus = CKEDITOR.env.needsBrFiller ? node.is && node.is( 'br' ) : node.getText && tailNbspRegex.test( node.getText() );
|
||||
|
||||
if ( isBogus ) {
|
||||
var parent = node.getParent(),
|
||||
next = node.getNext( nonEmpty );
|
||||
|
||||
isBogus = parent.isBlockBoundary() && ( !next || next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() );
|
||||
}
|
||||
|
||||
return !!( isReject ^ isBogus );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is a temporary element
|
||||
* (element with the `data-cke-temp` attribute) or its child.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false] Whether to return `false` for the
|
||||
* temporary element instead of `true` (default).
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.temp = function( isReject ) {
|
||||
return function( node ) {
|
||||
if ( node.type != CKEDITOR.NODE_ELEMENT )
|
||||
node = node.getParent();
|
||||
|
||||
var isTemp = node && node.hasAttribute( 'data-cke-temp' );
|
||||
|
||||
return !!( isReject ^ isTemp );
|
||||
};
|
||||
};
|
||||
|
||||
var tailNbspRegex = /^[\t\r\n ]*(?: |\xa0)$/,
|
||||
isWhitespaces = CKEDITOR.dom.walker.whitespaces(),
|
||||
isBookmark = CKEDITOR.dom.walker.bookmark(),
|
||||
isTemp = CKEDITOR.dom.walker.temp(),
|
||||
toSkip = function( node ) {
|
||||
return isBookmark( node ) ||
|
||||
isWhitespaces( node ) ||
|
||||
node.type == CKEDITOR.NODE_ELEMENT && node.is( CKEDITOR.dtd.$inline ) && !node.is( CKEDITOR.dtd.$empty );
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node should be ignored in terms of "editability".
|
||||
*
|
||||
* This includes:
|
||||
*
|
||||
* * whitespaces (see {@link CKEDITOR.dom.walker#whitespaces}),
|
||||
* * bookmarks (see {@link CKEDITOR.dom.walker#bookmark}),
|
||||
* * temporary elements (see {@link CKEDITOR.dom.walker#temp}).
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false] Whether to return `false` for the
|
||||
* ignored element instead of `true` (default).
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.ignored = function( isReject ) {
|
||||
return function( node ) {
|
||||
var isIgnored = isWhitespaces( node ) || isBookmark( node ) || isTemp( node );
|
||||
|
||||
return !!( isReject ^ isIgnored );
|
||||
};
|
||||
};
|
||||
|
||||
var isIgnored = CKEDITOR.dom.walker.ignored();
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is empty.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false] Whether to return `false` for the
|
||||
* ignored element instead of `true` (default).
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.empty = function( isReject ) {
|
||||
return function( node ) {
|
||||
var i = 0,
|
||||
l = node.getChildCount();
|
||||
|
||||
for ( ; i < l; ++i ) {
|
||||
if ( !isIgnored( node.getChild( i ) ) ) {
|
||||
return !!isReject;
|
||||
}
|
||||
}
|
||||
|
||||
return !isReject;
|
||||
};
|
||||
};
|
||||
|
||||
var isEmpty = CKEDITOR.dom.walker.empty();
|
||||
|
||||
function filterTextContainers( dtd ) {
|
||||
var hash = {},
|
||||
name;
|
||||
|
||||
for ( name in dtd ) {
|
||||
if ( CKEDITOR.dtd[ name ][ '#' ] )
|
||||
hash[ name ] = 1;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* A hash of element names which in browsers that {@link CKEDITOR.env#needsBrFiller do not need `<br>` fillers}
|
||||
* can be selection containers despite being empty.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @static
|
||||
* @property {Object} validEmptyBlockContainers
|
||||
*/
|
||||
var validEmptyBlocks = CKEDITOR.dom.walker.validEmptyBlockContainers = CKEDITOR.tools.extend(
|
||||
filterTextContainers( CKEDITOR.dtd.$block ),
|
||||
{ caption: 1, td: 1, th: 1 }
|
||||
);
|
||||
|
||||
function isEditable( node ) {
|
||||
// Skip temporary elements, bookmarks and whitespaces.
|
||||
if ( isIgnored( node ) )
|
||||
return false;
|
||||
|
||||
if ( node.type == CKEDITOR.NODE_TEXT )
|
||||
return true;
|
||||
|
||||
if ( node.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
// All inline and non-editable elements are valid editable places.
|
||||
// Note: the <hr> is currently the only element in CKEDITOR.dtd.$empty and CKEDITOR.dtd.$block,
|
||||
// but generally speaking we need an intersection of these two sets.
|
||||
// Note: non-editable block has to be treated differently (should be selected entirely).
|
||||
if ( node.is( CKEDITOR.dtd.$inline ) || node.is( 'hr' ) || node.getAttribute( 'contenteditable' ) == 'false' )
|
||||
return true;
|
||||
|
||||
// Empty blocks are editable on IE.
|
||||
if ( !CKEDITOR.env.needsBrFiller && node.is( validEmptyBlocks ) && isEmpty( node ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
// Skip all other nodes.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node can be a container or a sibling
|
||||
* of the selection end.
|
||||
*
|
||||
* This includes:
|
||||
*
|
||||
* * text nodes (but not whitespaces),
|
||||
* * inline elements,
|
||||
* * intersection of {@link CKEDITOR.dtd#$empty} and {@link CKEDITOR.dtd#$block} (currently
|
||||
* it is only `<hr>`),
|
||||
* * non-editable blocks (special case — such blocks cannot be containers nor
|
||||
* siblings, they need to be selected entirely),
|
||||
* * empty {@link #validEmptyBlockContainers blocks} which can contain text
|
||||
* ({@link CKEDITOR.env#needsBrFiller old IEs only}).
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false] Whether to return `false` for the
|
||||
* ignored element instead of `true` (default).
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.editable = function( isReject ) {
|
||||
return function( node ) {
|
||||
return !!( isReject ^ isEditable( node ) );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if there is a filler node at the end of an element, and returns it.
|
||||
*
|
||||
* @member CKEDITOR.dom.element
|
||||
* @returns {CKEDITOR.dom.node/Boolean} Bogus node or `false`.
|
||||
*/
|
||||
CKEDITOR.dom.element.prototype.getBogus = function() {
|
||||
// Bogus are not always at the end, e.g. <p><a>text<br /></a></p> (https://dev.ckeditor.com/ticket/7070).
|
||||
var tail = this;
|
||||
do {
|
||||
tail = tail.getPreviousSourceNode();
|
||||
}
|
||||
while ( toSkip( tail ) );
|
||||
|
||||
if ( tail && ( CKEDITOR.env.needsBrFiller ? tail.is && tail.is( 'br' ) : tail.getText && tailNbspRegex.test( tail.getText() ) ) )
|
||||
return tail;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
} )();
|
||||
95
Admin/plugins/ckeditor/core/dom/window.js
Normal file
95
Admin/plugins/ckeditor/core/dom/window.js
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.document} class, which
|
||||
* represents a DOM document.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a DOM window.
|
||||
*
|
||||
* var document = new CKEDITOR.dom.window( window );
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.dom.domObject
|
||||
* @constructor Creates a window class instance.
|
||||
* @param {Object} domWindow A native DOM window.
|
||||
*/
|
||||
CKEDITOR.dom.window = function( domWindow ) {
|
||||
CKEDITOR.dom.domObject.call( this, domWindow );
|
||||
};
|
||||
|
||||
CKEDITOR.dom.window.prototype = new CKEDITOR.dom.domObject();
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.window.prototype, {
|
||||
/**
|
||||
* Moves the selection focus to this window.
|
||||
*
|
||||
* var win = new CKEDITOR.dom.window( window );
|
||||
* win.focus();
|
||||
*/
|
||||
focus: function() {
|
||||
this.$.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the width and height of this window's viewable area.
|
||||
*
|
||||
* var win = new CKEDITOR.dom.window( window );
|
||||
* var size = win.getViewPaneSize();
|
||||
* alert( size.width );
|
||||
* alert( size.height );
|
||||
*
|
||||
* @returns {Object} An object with the `width` and `height`
|
||||
* properties containing the size.
|
||||
*/
|
||||
getViewPaneSize: function() {
|
||||
var doc = this.$.document,
|
||||
stdMode = doc.compatMode == 'CSS1Compat';
|
||||
return {
|
||||
width: ( stdMode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0,
|
||||
height: ( stdMode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the current position of the window's scroll.
|
||||
*
|
||||
* var win = new CKEDITOR.dom.window( window );
|
||||
* var pos = win.getScrollPosition();
|
||||
* alert( pos.x );
|
||||
* alert( pos.y );
|
||||
*
|
||||
* @returns {Object} An object with the `x` and `y` properties
|
||||
* containing the scroll position.
|
||||
*/
|
||||
getScrollPosition: function() {
|
||||
var $ = this.$;
|
||||
|
||||
if ( 'pageXOffset' in $ ) {
|
||||
return {
|
||||
x: $.pageXOffset || 0,
|
||||
y: $.pageYOffset || 0
|
||||
};
|
||||
} else {
|
||||
var doc = $.document;
|
||||
return {
|
||||
x: doc.documentElement.scrollLeft || doc.body.scrollLeft || 0,
|
||||
y: doc.documentElement.scrollTop || doc.body.scrollTop || 0
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the frame element containing this window context.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.element} The frame element or `null` if not in a frame context.
|
||||
*/
|
||||
getFrame: function() {
|
||||
var iframe = this.$.frameElement;
|
||||
return iframe ? new CKEDITOR.dom.element.get( iframe ) : null;
|
||||
}
|
||||
} );
|
||||
370
Admin/plugins/ckeditor/core/dtd.js
Normal file
370
Admin/plugins/ckeditor/core/dtd.js
Normal file
@@ -0,0 +1,370 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dtd} object, which holds the DTD
|
||||
* mapping for XHTML 1.0 Transitional. This file was automatically
|
||||
* generated from the file: xhtml1-transitional.dtd.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Holds and object representation of the HTML DTD to be used by the
|
||||
* editor in its internal operations.
|
||||
*
|
||||
* Each element in the DTD is represented by a property in this object. Each
|
||||
* property contains the list of elements that can be contained by the element.
|
||||
* Text is represented by the `#` property.
|
||||
*
|
||||
* Several special grouping properties are also available. Their names start
|
||||
* with the `$` character.
|
||||
*
|
||||
* // Check if <div> can be contained in a <p> element.
|
||||
* alert( !!CKEDITOR.dtd[ 'p' ][ 'div' ] ); // false
|
||||
*
|
||||
* // Check if <p> can be contained in a <div> element.
|
||||
* alert( !!CKEDITOR.dtd[ 'div' ][ 'p' ] ); // true
|
||||
*
|
||||
* // Check if <p> is a block element.
|
||||
* alert( !!CKEDITOR.dtd.$block[ 'p' ] ); // true
|
||||
*
|
||||
* It is also possible to add a new element to DTD. It will ensure it is handled correctly e.g. in terms of nesting or positioning.
|
||||
*
|
||||
* For example, you can define a block element, which can be empty:
|
||||
*
|
||||
* ```js
|
||||
* // Let's add a DTD for a new element <signature>
|
||||
* // and specify it can contain <p> and <img> elements:
|
||||
* CKEDITOR.dtd[ 'signature' ] = {
|
||||
* p: 1,
|
||||
* img: 1
|
||||
* };
|
||||
*
|
||||
* // Define <signature> as a block element.
|
||||
* CKEDITOR.dtd.$block[ 'signature' ] = 1;
|
||||
*
|
||||
* // Allow <signature> element to be empty.
|
||||
* CKEDITOR.dtd.$empty[ 'signature' ] = 1;
|
||||
* ```
|
||||
*
|
||||
* **Note**: Editing the DTD for existing elements is also possible this way, but may cause an unexpected outcome and inconsistent editing behaviour, so **it is not recommended**.
|
||||
*
|
||||
* @class CKEDITOR.dtd
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.dtd = ( function() {
|
||||
'use strict';
|
||||
|
||||
var X = CKEDITOR.tools.extend,
|
||||
// Subtraction rest of sets, from the first set.
|
||||
Y = function( source, removed ) {
|
||||
var substracted = CKEDITOR.tools.clone( source );
|
||||
for ( var i = 1; i < arguments.length; i++ ) {
|
||||
removed = arguments[ i ];
|
||||
for ( var name in removed )
|
||||
delete substracted[ name ];
|
||||
}
|
||||
return substracted;
|
||||
};
|
||||
|
||||
// Phrasing elements.
|
||||
// P = { a: 1, em: 1, strong: 1, small: 1, abbr: 1, dfn: 1, i: 1, b: 1, s: 1,
|
||||
// u: 1, code: 1, 'var': 1, samp: 1, kbd: 1, sup: 1, sub: 1, q: 1, cite: 1,
|
||||
// span: 1, bdo: 1, bdi: 1, br: 1, wbr: 1, ins: 1, del: 1, img: 1, embed: 1,
|
||||
// object: 1, iframe: 1, map: 1, area: 1, script: 1, noscript: 1, ruby: 1,
|
||||
// video: 1, audio: 1, input: 1, textarea: 1, select: 1, button: 1, label: 1,
|
||||
// output: 1, keygen: 1, progress: 1, command: 1, canvas: 1, time: 1,
|
||||
// meter: 1, detalist: 1 },
|
||||
|
||||
// Flow elements.
|
||||
// F = { a: 1, p: 1, hr: 1, pre: 1, ul: 1, ol: 1, dl: 1, div: 1, h1: 1, h2: 1,
|
||||
// h3: 1, h4: 1, h5: 1, h6: 1, hgroup: 1, address: 1, blockquote: 1, ins: 1,
|
||||
// del: 1, object: 1, map: 1, noscript: 1, section: 1, nav: 1, article: 1,
|
||||
// aside: 1, header: 1, footer: 1, video: 1, audio: 1, figure: 1, table: 1,
|
||||
// form: 1, fieldset: 1, menu: 1, canvas: 1, details:1 },
|
||||
|
||||
// Text can be everywhere.
|
||||
// X( P, T );
|
||||
// Flow elements set consists of phrasing elements set.
|
||||
// X( F, P );
|
||||
|
||||
var P = {}, F = {},
|
||||
// Intersection of flow elements set and phrasing elements set.
|
||||
PF = {
|
||||
a: 1, abbr: 1, area: 1, audio: 1, b: 1, bdi: 1, bdo: 1, br: 1, button: 1, canvas: 1, cite: 1,
|
||||
code: 1, command: 1, datalist: 1, del: 1, dfn: 1, em: 1, embed: 1, i: 1, iframe: 1, img: 1,
|
||||
input: 1, ins: 1, kbd: 1, keygen: 1, label: 1, map: 1, mark: 1, meter: 1, noscript: 1, object: 1,
|
||||
output: 1, progress: 1, q: 1, ruby: 1, s: 1, samp: 1, script: 1, select: 1, small: 1, span: 1,
|
||||
strong: 1, sub: 1, sup: 1, textarea: 1, time: 1, u: 1, 'var': 1, video: 1, wbr: 1
|
||||
},
|
||||
// F - PF (Flow Only).
|
||||
FO = {
|
||||
address: 1, article: 1, aside: 1, blockquote: 1, details: 1, div: 1, dl: 1, fieldset: 1,
|
||||
figure: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, header: 1, hgroup: 1,
|
||||
hr: 1, main: 1, menu: 1, nav: 1, ol: 1, p: 1, pre: 1, section: 1, table: 1, ul: 1
|
||||
},
|
||||
// Metadata elements.
|
||||
M = { command: 1, link: 1, meta: 1, noscript: 1, script: 1, style: 1 },
|
||||
// Empty.
|
||||
E = {},
|
||||
// Text.
|
||||
T = { '#': 1 },
|
||||
|
||||
// Deprecated phrasing elements.
|
||||
DP = { acronym: 1, applet: 1, basefont: 1, big: 1, font: 1, isindex: 1, strike: 1, style: 1, tt: 1 }, // TODO remove "style".
|
||||
// Deprecated flow only elements.
|
||||
DFO = { center: 1, dir: 1, noframes: 1 };
|
||||
|
||||
// Phrasing elements := PF + T + DP
|
||||
X( P, PF, T, DP );
|
||||
// Flow elements := FO + P + DFO
|
||||
X( F, FO, P, DFO );
|
||||
|
||||
var dtd = {
|
||||
a: Y( P, { a: 1, button: 1 } ), // Treat as normal inline element (not a transparent one).
|
||||
abbr: P,
|
||||
address: F,
|
||||
area: E,
|
||||
article: F,
|
||||
aside: F,
|
||||
audio: X( { source: 1, track: 1 }, F ),
|
||||
b: P,
|
||||
base: E,
|
||||
bdi: P,
|
||||
bdo: P,
|
||||
blockquote: F,
|
||||
body: F,
|
||||
br: E,
|
||||
button: Y( P, { a: 1, button: 1 } ),
|
||||
canvas: P, // Treat as normal inline element (not a transparent one).
|
||||
caption: F,
|
||||
cite: P,
|
||||
code: P,
|
||||
col: E,
|
||||
colgroup: { col: 1 },
|
||||
command: E,
|
||||
datalist: X( { option: 1 }, P ),
|
||||
dd: F,
|
||||
del: P, // Treat as normal inline element (not a transparent one).
|
||||
details: X( { summary: 1 }, F ),
|
||||
dfn: P,
|
||||
div: F,
|
||||
dl: { dt: 1, dd: 1 },
|
||||
dt: F,
|
||||
em: P,
|
||||
embed: E,
|
||||
fieldset: X( { legend: 1 }, F ),
|
||||
figcaption: F,
|
||||
figure: X( { figcaption: 1 }, F ),
|
||||
footer: F,
|
||||
form: F,
|
||||
h1: P,
|
||||
h2: P,
|
||||
h3: P,
|
||||
h4: P,
|
||||
h5: P,
|
||||
h6: P,
|
||||
head: X( { title: 1, base: 1 }, M ),
|
||||
header: F,
|
||||
hgroup: { h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1 },
|
||||
hr: E,
|
||||
html: X( { head: 1, body: 1 }, F, M ), // Head and body are optional...
|
||||
i: P,
|
||||
iframe: T,
|
||||
img: E,
|
||||
input: E,
|
||||
ins: P, // Treat as normal inline element (not a transparent one).
|
||||
kbd: P,
|
||||
keygen: E,
|
||||
label: P,
|
||||
legend: P,
|
||||
li: F,
|
||||
link: E,
|
||||
// Can't be a descendant of article, aside, footer, header, nav, but we don't need this
|
||||
// complication. As well as checking if it's used only once.
|
||||
main: F,
|
||||
map: F,
|
||||
mark: P, // Treat as normal inline element (not a transparent one).
|
||||
menu: X( { li: 1 }, F ),
|
||||
meta: E,
|
||||
meter: Y( P, { meter: 1 } ),
|
||||
nav: F,
|
||||
noscript: X( { link: 1, meta: 1, style: 1 }, P ), // Treat as normal inline element (not a transparent one).
|
||||
object: X( { param: 1 }, P ), // Treat as normal inline element (not a transparent one).
|
||||
ol: { li: 1 },
|
||||
optgroup: { option: 1 },
|
||||
option: T,
|
||||
output: P,
|
||||
p: P,
|
||||
param: E,
|
||||
pre: P,
|
||||
progress: Y( P, { progress: 1 } ),
|
||||
q: P,
|
||||
rp: P,
|
||||
rt: P,
|
||||
ruby: X( { rp: 1, rt: 1 }, P ),
|
||||
s: P,
|
||||
samp: P,
|
||||
script: T,
|
||||
section: F,
|
||||
select: { optgroup: 1, option: 1 },
|
||||
small: P,
|
||||
source: E,
|
||||
span: P,
|
||||
strong: P,
|
||||
style: T,
|
||||
sub: P,
|
||||
summary: X( { h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1 }, P ),
|
||||
sup: P,
|
||||
table: { caption: 1, colgroup: 1, thead: 1, tfoot: 1, tbody: 1, tr: 1 },
|
||||
tbody: { tr: 1 },
|
||||
td: F,
|
||||
textarea: T,
|
||||
tfoot: { tr: 1 },
|
||||
th: F,
|
||||
thead: { tr: 1 },
|
||||
time: Y( P, { time: 1 } ),
|
||||
title: T,
|
||||
tr: { th: 1, td: 1 },
|
||||
track: E,
|
||||
u: P,
|
||||
ul: { li: 1 },
|
||||
'var': P,
|
||||
video: X( { source: 1, track: 1 }, F ),
|
||||
wbr: E,
|
||||
|
||||
// Deprecated tags.
|
||||
acronym: P,
|
||||
applet: X( { param: 1 }, F ),
|
||||
basefont: E,
|
||||
big: P,
|
||||
center: F,
|
||||
dialog: E,
|
||||
dir: { li: 1 },
|
||||
font: P,
|
||||
isindex: E,
|
||||
noframes: F,
|
||||
strike: P,
|
||||
tt: P
|
||||
};
|
||||
|
||||
X( dtd, {
|
||||
/**
|
||||
* List of block elements, like `<p>` or `<div>`.
|
||||
*/
|
||||
$block: X( { audio: 1, dd: 1, dt: 1, figcaption: 1, li: 1, video: 1 }, FO, DFO ),
|
||||
|
||||
/**
|
||||
* List of elements that contain other blocks, in which block-level operations should be limited,
|
||||
* this property is not intended to be checked directly, use {@link CKEDITOR.dom.elementPath#blockLimit} instead.
|
||||
*
|
||||
* Some examples of editor behaviors that are impacted by block limits:
|
||||
*
|
||||
* * Enter key never split a block-limit element;
|
||||
* * Style application is constraint by the block limit of the current selection.
|
||||
* * Pasted html will be inserted into the block limit of the current selection.
|
||||
*
|
||||
* **Note:** As an exception `<li>` is not considered as a block limit, as it's generally used as a text block.
|
||||
*/
|
||||
$blockLimit: {
|
||||
article: 1, aside: 1, audio: 1, body: 1, caption: 1, details: 1, dir: 1, div: 1, dl: 1,
|
||||
fieldset: 1, figcaption: 1, figure: 1, footer: 1, form: 1, header: 1, hgroup: 1, main: 1, menu: 1, nav: 1,
|
||||
ol: 1, section: 1, table: 1, td: 1, th: 1, tr: 1, ul: 1, video: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* List of elements that contain character data.
|
||||
*/
|
||||
$cdata: { script: 1, style: 1 },
|
||||
|
||||
/**
|
||||
* List of elements that are accepted as inline editing hosts.
|
||||
*/
|
||||
$editable: {
|
||||
address: 1, article: 1, aside: 1, blockquote: 1, body: 1, details: 1, div: 1, fieldset: 1,
|
||||
figcaption: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, header: 1, hgroup: 1,
|
||||
main: 1, nav: 1, p: 1, pre: 1, section: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* List of empty (self-closing) elements, like `<br>` or `<img>`.
|
||||
*/
|
||||
$empty: {
|
||||
area: 1, base: 1, basefont: 1, br: 1, col: 1, command: 1, dialog: 1, embed: 1, hr: 1, img: 1,
|
||||
input: 1, isindex: 1, keygen: 1, link: 1, meta: 1, param: 1, source: 1, track: 1, wbr: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* List of inline (`<span>` like) elements.
|
||||
*/
|
||||
$inline: P,
|
||||
|
||||
/**
|
||||
* List of list root elements.
|
||||
*/
|
||||
$list: { dl: 1, ol: 1, ul: 1 },
|
||||
|
||||
/**
|
||||
* List of list item elements, like `<li>` or `<dd>`.
|
||||
*/
|
||||
$listItem: { dd: 1, dt: 1, li: 1 },
|
||||
|
||||
/**
|
||||
* List of elements which may live outside body.
|
||||
*/
|
||||
$nonBodyContent: X( { body: 1, head: 1, html: 1 }, dtd.head ),
|
||||
|
||||
/**
|
||||
* Elements that accept text nodes, but are not possible to edit into the browser.
|
||||
*/
|
||||
$nonEditable: {
|
||||
applet: 1, audio: 1, button: 1, embed: 1, iframe: 1, map: 1, object: 1, option: 1,
|
||||
param: 1, script: 1, textarea: 1, video: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* Elements that are considered objects, therefore selected as a whole in the editor.
|
||||
*/
|
||||
$object: {
|
||||
applet: 1, audio: 1, button: 1, hr: 1, iframe: 1, img: 1, input: 1, object: 1, select: 1,
|
||||
table: 1, textarea: 1, video: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* List of elements that can be ignored if empty, like `<b>` or `<span>`.
|
||||
*/
|
||||
$removeEmpty: {
|
||||
abbr: 1, acronym: 1, b: 1, bdi: 1, bdo: 1, big: 1, cite: 1, code: 1, del: 1, dfn: 1,
|
||||
em: 1, font: 1, i: 1, ins: 1, label: 1, kbd: 1, mark: 1, meter: 1, output: 1, q: 1, ruby: 1, s: 1,
|
||||
samp: 1, small: 1, span: 1, strike: 1, strong: 1, sub: 1, sup: 1, time: 1, tt: 1, u: 1, 'var': 1
|
||||
},
|
||||
|
||||
/**
|
||||
* List of elements that have tabindex set to zero by default.
|
||||
*/
|
||||
$tabIndex: { a: 1, area: 1, button: 1, input: 1, object: 1, select: 1, textarea: 1 },
|
||||
|
||||
/**
|
||||
* List of elements used inside the `<table>` element, like `<tbody>` or `<td>`.
|
||||
*/
|
||||
$tableContent: { caption: 1, col: 1, colgroup: 1, tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, tr: 1 },
|
||||
|
||||
/**
|
||||
* List of "transparent" elements. See [W3C's definition of "transparent" element](http://dev.w3.org/html5/markup/terminology.html#transparent).
|
||||
*/
|
||||
$transparent: { a: 1, audio: 1, canvas: 1, del: 1, ins: 1, map: 1, noscript: 1, object: 1, video: 1 },
|
||||
|
||||
/**
|
||||
* List of elements that are not to exist standalone that must live under it's parent element.
|
||||
*/
|
||||
$intermediate: {
|
||||
caption: 1, colgroup: 1, dd: 1, dt: 1, figcaption: 1, legend: 1, li: 1, optgroup: 1,
|
||||
option: 1, rp: 1, rt: 1, summary: 1, tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, tr: 1
|
||||
}
|
||||
} );
|
||||
|
||||
return dtd;
|
||||
} )();
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.dtd )
|
||||
3507
Admin/plugins/ckeditor/core/editable.js
Normal file
3507
Admin/plugins/ckeditor/core/editable.js
Normal file
File diff suppressed because it is too large
Load Diff
2453
Admin/plugins/ckeditor/core/editor.js
Normal file
2453
Admin/plugins/ckeditor/core/editor.js
Normal file
File diff suppressed because it is too large
Load Diff
36
Admin/plugins/ckeditor/core/editor_basic.js
Normal file
36
Admin/plugins/ckeditor/core/editor_basic.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
if ( !CKEDITOR.editor ) {
|
||||
// Documented at editor.js.
|
||||
CKEDITOR.editor = function() {
|
||||
// Push this editor to the pending list. It'll be processed later once
|
||||
// the full editor code is loaded.
|
||||
CKEDITOR._.pending.push( [ this, arguments ] );
|
||||
|
||||
// Call the CKEDITOR.event constructor to initialize this instance.
|
||||
CKEDITOR.event.call( this );
|
||||
};
|
||||
|
||||
// Both fire and fireOnce will always pass this editor instance as the
|
||||
// "editor" param in CKEDITOR.event.fire. So, we override it to do that
|
||||
// automaticaly.
|
||||
CKEDITOR.editor.prototype.fire = function( eventName, data ) {
|
||||
if ( eventName in { instanceReady: 1, loaded: 1 } )
|
||||
this[ eventName ] = true;
|
||||
|
||||
return CKEDITOR.event.prototype.fire.call( this, eventName, data, this );
|
||||
};
|
||||
|
||||
CKEDITOR.editor.prototype.fireOnce = function( eventName, data ) {
|
||||
if ( eventName in { instanceReady: 1, loaded: 1 } )
|
||||
this[ eventName ] = true;
|
||||
|
||||
return CKEDITOR.event.prototype.fireOnce.call( this, eventName, data, this );
|
||||
};
|
||||
|
||||
// "Inherit" (copy actually) from CKEDITOR.event.
|
||||
CKEDITOR.event.implementOn( CKEDITOR.editor.prototype );
|
||||
}
|
||||
361
Admin/plugins/ckeditor/core/env.js
Normal file
361
Admin/plugins/ckeditor/core/env.js
Normal file
@@ -0,0 +1,361 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.env} object which contains
|
||||
* environment and browser information.
|
||||
*/
|
||||
|
||||
if ( !CKEDITOR.env ) {
|
||||
/**
|
||||
* Environment and browser information.
|
||||
*
|
||||
* @class CKEDITOR.env
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.env = ( function() {
|
||||
var agent = navigator.userAgent.toLowerCase(),
|
||||
edge = agent.match( /edge[ \/](\d+.?\d*)/ ),
|
||||
trident = agent.indexOf( 'trident/' ) > -1,
|
||||
ie = !!( edge || trident );
|
||||
|
||||
var env = {
|
||||
/**
|
||||
* Indicates that CKEditor is running in Internet Explorer.
|
||||
*
|
||||
* if ( CKEDITOR.env.ie )
|
||||
* alert( 'I\'m running in IE!' );
|
||||
*
|
||||
* **Note:** This property is also set to `true` if CKEditor is running
|
||||
* in {@link #edge Microsoft Edge}.
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
ie: ie,
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in Microsoft Edge.
|
||||
*
|
||||
* if ( CKEDITOR.env.edge )
|
||||
* alert( 'I\'m running in Edge!' );
|
||||
*
|
||||
* See also {@link #ie}.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @property {Boolean}
|
||||
*/
|
||||
edge: !!edge,
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a WebKit-based browser, like Safari,
|
||||
* or Blink-based browser, like Chrome.
|
||||
*
|
||||
* if ( CKEDITOR.env.webkit )
|
||||
* alert( 'I\'m running in a WebKit browser!' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
webkit: !ie && ( agent.indexOf( ' applewebkit/' ) > -1 ),
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in Adobe AIR.
|
||||
*
|
||||
* if ( CKEDITOR.env.air )
|
||||
* alert( 'I\'m on AIR!' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
air: ( agent.indexOf( ' adobeair/' ) > -1 ),
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running on Macintosh.
|
||||
*
|
||||
* if ( CKEDITOR.env.mac )
|
||||
* alert( 'I love apples!'' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
mac: ( agent.indexOf( 'macintosh' ) > -1 ),
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a Quirks Mode environment.
|
||||
*
|
||||
* if ( CKEDITOR.env.quirks )
|
||||
* alert( 'Nooooo!' );
|
||||
*
|
||||
* Internet Explorer 10 introduced the _New Quirks Mode_, which is similar to the _Quirks Mode_
|
||||
* implemented in other modern browsers and defined in the HTML5 specification. It can be handled
|
||||
* as the Standards mode, so the value of this property will be set to `false`.
|
||||
*
|
||||
* The _Internet Explorer 5 Quirks_ mode which is still available in Internet Explorer 10+
|
||||
* sets this value to `true` and {@link #version} to `7`.
|
||||
*
|
||||
* Read more: [IEBlog](http://blogs.msdn.com/b/ie/archive/2011/12/14/interoperable-html5-quirks-mode-in-ie10.aspx)
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
quirks: ( document.compatMode == 'BackCompat' && ( !document.documentMode || document.documentMode < 10 ) ),
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a mobile environemnt.
|
||||
*
|
||||
* if ( CKEDITOR.env.mobile )
|
||||
* alert( 'I\'m running with CKEditor today!' );
|
||||
*
|
||||
* @deprecated
|
||||
* @property {Boolean}
|
||||
*/
|
||||
mobile: ( agent.indexOf( 'mobile' ) > -1 ),
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running on Apple iPhone/iPad/iPod devices.
|
||||
*
|
||||
* if ( CKEDITOR.env.iOS )
|
||||
* alert( 'I like little apples!' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
iOS: /(ipad|iphone|ipod)/.test( agent ),
|
||||
|
||||
/**
|
||||
* Indicates that the browser has a custom domain enabled. This has
|
||||
* been set with `document.domain`.
|
||||
*
|
||||
* if ( CKEDITOR.env.isCustomDomain() )
|
||||
* alert( 'I\'m in a custom domain!' );
|
||||
*
|
||||
* @returns {Boolean} `true` if a custom domain is enabled.
|
||||
* @deprecated
|
||||
*/
|
||||
isCustomDomain: function() {
|
||||
if ( !this.ie )
|
||||
return false;
|
||||
|
||||
var domain = document.domain,
|
||||
hostname = window.location.hostname;
|
||||
|
||||
return domain != hostname && domain != ( '[' + hostname + ']' ); // IPv6 IP support (https://dev.ckeditor.com/ticket/5434)
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates that the page is running under an encrypted connection.
|
||||
*
|
||||
* if ( CKEDITOR.env.secure )
|
||||
* alert( 'I\'m on SSL!' );
|
||||
*
|
||||
* @returns {Boolean} `true` if the page has an encrypted connection.
|
||||
*/
|
||||
secure: location.protocol == 'https:'
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a Gecko-based browser, like
|
||||
* Firefox.
|
||||
*
|
||||
* if ( CKEDITOR.env.gecko )
|
||||
* alert( 'I\'m riding a gecko!' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
env.gecko = ( navigator.product == 'Gecko' && !env.webkit && !env.ie );
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a Blink-based browser like Chrome.
|
||||
*
|
||||
* if ( CKEDITOR.env.chrome )
|
||||
* alert( 'I\'m running in Chrome!' );
|
||||
*
|
||||
* @property {Boolean} chrome
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in Safari (including the mobile version).
|
||||
*
|
||||
* if ( CKEDITOR.env.safari )
|
||||
* alert( 'I\'m on Safari!' );
|
||||
*
|
||||
* @property {Boolean} safari
|
||||
*/
|
||||
if ( env.webkit ) {
|
||||
if ( agent.indexOf( 'chrome' ) > -1 )
|
||||
env.chrome = true;
|
||||
else
|
||||
env.safari = true;
|
||||
}
|
||||
|
||||
var version = 0;
|
||||
|
||||
// Internet Explorer 6.0+
|
||||
if ( env.ie ) {
|
||||
// We use env.version for feature detection, so set it properly.
|
||||
if ( edge ) {
|
||||
version = parseFloat( edge[ 1 ] );
|
||||
} else if ( env.quirks || !document.documentMode ) {
|
||||
version = parseFloat( agent.match( /msie (\d+)/ )[ 1 ] );
|
||||
} else {
|
||||
version = document.documentMode;
|
||||
}
|
||||
|
||||
// Deprecated features available just for backwards compatibility.
|
||||
env.ie9Compat = version == 9;
|
||||
env.ie8Compat = version == 8;
|
||||
env.ie7Compat = version == 7;
|
||||
env.ie6Compat = version < 7 || env.quirks;
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in an IE6-like environment, which
|
||||
* includes IE6 itself as well as IE7, IE8 and IE9 in Quirks Mode.
|
||||
*
|
||||
* @deprecated
|
||||
* @property {Boolean} ie6Compat
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in an IE7-like environment, which
|
||||
* includes IE7 itself and IE8's IE7 Document Mode.
|
||||
*
|
||||
* @deprecated
|
||||
* @property {Boolean} ie7Compat
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in Internet Explorer 8 on
|
||||
* Standards Mode.
|
||||
*
|
||||
* @deprecated
|
||||
* @property {Boolean} ie8Compat
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in Internet Explorer 9 on
|
||||
* Standards Mode.
|
||||
*
|
||||
* @deprecated
|
||||
* @property {Boolean} ie9Compat
|
||||
*/
|
||||
}
|
||||
|
||||
// Gecko.
|
||||
if ( env.gecko ) {
|
||||
var geckoRelease = agent.match( /rv:([\d\.]+)/ );
|
||||
if ( geckoRelease ) {
|
||||
geckoRelease = geckoRelease[ 1 ].split( '.' );
|
||||
version = geckoRelease[ 0 ] * 10000 + ( geckoRelease[ 1 ] || 0 ) * 100 + ( geckoRelease[ 2 ] || 0 ) * 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Adobe AIR 1.0+
|
||||
// Checked before Safari because AIR have the WebKit rich text editor
|
||||
// features from Safari 3.0.4, but the version reported is 420.
|
||||
if ( env.air )
|
||||
version = parseFloat( agent.match( / adobeair\/(\d+)/ )[ 1 ] );
|
||||
|
||||
// WebKit 522+ (Safari 3+)
|
||||
if ( env.webkit )
|
||||
version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[ 1 ] );
|
||||
|
||||
/**
|
||||
* Contains the browser version.
|
||||
*
|
||||
* For Gecko-based browsers (like Firefox) it contains the revision
|
||||
* number with first three parts concatenated with a padding zero
|
||||
* (e.g. for revision 1.9.0.2 we have 10900).
|
||||
*
|
||||
* For WebKit-based browsers (like Safari and Chrome) it contains the
|
||||
* WebKit build version (e.g. 522).
|
||||
*
|
||||
* For IE browsers, it matches the "Document Mode".
|
||||
*
|
||||
* if ( CKEDITOR.env.ie && CKEDITOR.env.version <= 6 )
|
||||
* alert( 'Ouch!' );
|
||||
*
|
||||
* @property {Number}
|
||||
*/
|
||||
env.version = version;
|
||||
|
||||
/**
|
||||
* Since CKEditor 4.5.0 this property is a blacklist of browsers incompatible with CKEditor. It means that it is
|
||||
* set to `false` only in browsers that are known to be incompatible. Before CKEditor 4.5.0 this
|
||||
* property was a whitelist of browsers that were known to be compatible with CKEditor.
|
||||
*
|
||||
* The reason for this change is the rising fragmentation of the browser market (especially the mobile segment).
|
||||
* It became too complicated to check in which new environments CKEditor is going to work.
|
||||
*
|
||||
* In order to enable CKEditor 4.4.x and below in unsupported environments see the
|
||||
* {@glink guide/dev_unsupported_environments Enabling CKEditor in Unsupported Environments} article.
|
||||
*
|
||||
* if ( CKEDITOR.env.isCompatible )
|
||||
* alert( 'Your browser is not known to be incompatible with CKEditor!' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
env.isCompatible =
|
||||
// IE 7+ (IE 7 is not supported, but IE Compat Mode is and it is recognized as IE7).
|
||||
!( env.ie && version < 7 ) &&
|
||||
// Firefox 4.0+.
|
||||
!( env.gecko && version < 40000 ) &&
|
||||
// Chrome 6+, Safari 5.1+, iOS 5+.
|
||||
!( env.webkit && version < 534 );
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in the HiDPI environment.
|
||||
*
|
||||
* if ( CKEDITOR.env.hidpi )
|
||||
* alert( 'You are using a screen with high pixel density.' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
env.hidpi = window.devicePixelRatio >= 2;
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a browser which uses a bogus
|
||||
* `<br>` filler in order to correctly display caret in empty blocks.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @property {Boolean}
|
||||
*/
|
||||
env.needsBrFiller = env.gecko || env.webkit || ( env.ie && version > 10 );
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a browser which needs a
|
||||
* non-breaking space filler in order to correctly display caret in empty blocks.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @property {Boolean}
|
||||
*/
|
||||
env.needsNbspFiller = env.ie && version < 11;
|
||||
|
||||
/**
|
||||
* A CSS class that denotes the browser where CKEditor runs and is appended
|
||||
* to the HTML element that contains the editor. It makes it easier to apply
|
||||
* browser-specific styles to editor instances.
|
||||
*
|
||||
* myDiv.className = CKEDITOR.env.cssClass;
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
env.cssClass = 'cke_browser_' + ( env.ie ? 'ie' : env.gecko ? 'gecko' : env.webkit ? 'webkit' : 'unknown' );
|
||||
|
||||
if ( env.quirks )
|
||||
env.cssClass += ' cke_browser_quirks';
|
||||
|
||||
if ( env.ie )
|
||||
env.cssClass += ' cke_browser_ie' + ( env.quirks ? '6 cke_browser_iequirks' : env.version );
|
||||
|
||||
if ( env.air )
|
||||
env.cssClass += ' cke_browser_air';
|
||||
|
||||
if ( env.iOS )
|
||||
env.cssClass += ' cke_browser_ios';
|
||||
|
||||
if ( env.hidpi )
|
||||
env.cssClass += ' cke_hidpi';
|
||||
|
||||
return env;
|
||||
} )();
|
||||
}
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.env )
|
||||
// PACKAGER_RENAME( CKEDITOR.env.ie )
|
||||
413
Admin/plugins/ckeditor/core/event.js
Normal file
413
Admin/plugins/ckeditor/core/event.js
Normal file
@@ -0,0 +1,413 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.event} class, which serves as the
|
||||
* base for classes and objects that require event handling features.
|
||||
*/
|
||||
|
||||
( function() {
|
||||
'use strict';
|
||||
|
||||
// Instead of false, we mark event cancellation with unique object (#4652).
|
||||
var EVENT_CANCELED = {};
|
||||
|
||||
if ( !CKEDITOR.event ) {
|
||||
/**
|
||||
* Creates an event class instance. This constructor is rarely used, being
|
||||
* the {@link #implementOn} function used in class prototypes directly
|
||||
* instead.
|
||||
*
|
||||
* This is a base class for classes and objects that require event
|
||||
* handling features.
|
||||
*
|
||||
* Do not confuse this class with {@link CKEDITOR.dom.event} which is
|
||||
* instead used for DOM events. The CKEDITOR.event class implements the
|
||||
* internal event system used by the CKEditor to fire API related events.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates an event class instance.
|
||||
*/
|
||||
CKEDITOR.event = function() {};
|
||||
|
||||
/**
|
||||
* Implements the {@link CKEDITOR.event} features in an object.
|
||||
*
|
||||
* var myObject = { message: 'Example' };
|
||||
* CKEDITOR.event.implementOn( myObject );
|
||||
*
|
||||
* myObject.on( 'testEvent', function() {
|
||||
* alert( this.message );
|
||||
* } );
|
||||
* myObject.fire( 'testEvent' ); // 'Example'
|
||||
*
|
||||
* @static
|
||||
* @param {Object} targetObject The object into which implement the features.
|
||||
*/
|
||||
CKEDITOR.event.implementOn = function( targetObject ) {
|
||||
var eventProto = CKEDITOR.event.prototype;
|
||||
|
||||
for ( var prop in eventProto ) {
|
||||
if ( targetObject[ prop ] == null )
|
||||
targetObject[ prop ] = eventProto[ prop ];
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.event.prototype = ( function() {
|
||||
// Returns the private events object for a given object.
|
||||
var getPrivate = function( obj ) {
|
||||
var _ = ( obj.getPrivate && obj.getPrivate() ) || obj._ || ( obj._ = {} );
|
||||
return _.events || ( _.events = {} );
|
||||
};
|
||||
|
||||
var eventEntry = function( eventName ) {
|
||||
this.name = eventName;
|
||||
this.listeners = [];
|
||||
};
|
||||
|
||||
eventEntry.prototype = {
|
||||
// Get the listener index for a specified function.
|
||||
// Returns -1 if not found.
|
||||
getListenerIndex: function( listenerFunction ) {
|
||||
for ( var i = 0, listeners = this.listeners; i < listeners.length; i++ ) {
|
||||
if ( listeners[ i ].fn == listenerFunction )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
// Retrieve the event entry on the event host (create it if needed).
|
||||
function getEntry( name ) {
|
||||
// Get the event entry (create it if needed).
|
||||
var events = getPrivate( this );
|
||||
return events[ name ] || ( events[ name ] = new eventEntry( name ) );
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Predefine some intrinsic properties on a specific event name.
|
||||
*
|
||||
* @param {String} name The event name
|
||||
* @param meta
|
||||
* @param [meta.errorProof=false] Whether the event firing should catch error thrown from a per listener call.
|
||||
*/
|
||||
define: function( name, meta ) {
|
||||
var entry = getEntry.call( this, name );
|
||||
CKEDITOR.tools.extend( entry, meta, true );
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a listener to a specific event in the current object.
|
||||
*
|
||||
* ```javascript
|
||||
* someObject.on( 'someEvent', function() {
|
||||
* alert( this == someObject ); // true
|
||||
* } );
|
||||
*
|
||||
* someObject.on( 'someEvent', function() {
|
||||
* alert( this == anotherObject ); // true
|
||||
* }, anotherObject );
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.listenerData ); // 'Example'
|
||||
* }, null, 'Example' );
|
||||
*
|
||||
* someObject.on( 'someEvent', function() { ... } ); // 2nd called
|
||||
* someObject.on( 'someEvent', function() { ... }, null, null, 100 ); // 3rd called
|
||||
* someObject.on( 'someEvent', function() { ... }, null, null, 1 ); // 1st called
|
||||
* ```
|
||||
*
|
||||
* **Note**: CKEditor's event system has a limitation that one function cannot be used as a listener for the same event more than once.
|
||||
* Hence, to reuse it with multiple listeners, it should be wrapped into additional wrapper function:
|
||||
*
|
||||
* ```javascript
|
||||
* function listener( evt ) { ... };
|
||||
*
|
||||
* someObject.on( 'someEvent', function() {
|
||||
* listener();
|
||||
* } );
|
||||
*
|
||||
* someObject.on( 'someEvent', function( evt ) {
|
||||
* listener( evt );
|
||||
* } );
|
||||
* ```
|
||||
*
|
||||
* @param {String} eventName The event name to which listen.
|
||||
* @param {Function} listenerFunction The function listening to the
|
||||
* event. A single {@link CKEDITOR.eventInfo} object instanced
|
||||
* is passed to this function containing all the event data.
|
||||
* @param {Object} [scopeObj] The object used to scope the listener
|
||||
* call (the `this` object). If omitted, the current object is used.
|
||||
* @param {Object} [listenerData] Data to be sent as the
|
||||
* {@link CKEDITOR.eventInfo#listenerData} when calling the
|
||||
* listener.
|
||||
* @param {Number} [priority=10] The listener priority. Lower priority
|
||||
* listeners are called first. Listeners with the same priority
|
||||
* value are called in registration order.
|
||||
* @returns {Object} An object containing the `removeListener`
|
||||
* function, which can be used to remove the listener at any time.
|
||||
*/
|
||||
on: function( eventName, listenerFunction, scopeObj, listenerData, priority ) {
|
||||
var me = this;
|
||||
|
||||
// Create the function to be fired for this listener.
|
||||
function listenerFirer( editor, publisherData, stopFn, cancelFn ) {
|
||||
var ev = {
|
||||
name: eventName,
|
||||
sender: this,
|
||||
editor: editor,
|
||||
data: publisherData,
|
||||
listenerData: listenerData,
|
||||
stop: stopFn,
|
||||
cancel: cancelFn,
|
||||
removeListener: removeListener
|
||||
};
|
||||
|
||||
var ret = listenerFunction.call( scopeObj, ev );
|
||||
|
||||
return ret === false ? EVENT_CANCELED : ev.data;
|
||||
}
|
||||
|
||||
function removeListener() {
|
||||
me.removeListener( eventName, listenerFunction );
|
||||
}
|
||||
|
||||
var event = getEntry.call( this, eventName );
|
||||
|
||||
if ( event.getListenerIndex( listenerFunction ) < 0 ) {
|
||||
// Get the listeners.
|
||||
var listeners = event.listeners;
|
||||
|
||||
// Fill the scope.
|
||||
if ( !scopeObj )
|
||||
scopeObj = this;
|
||||
|
||||
// Default the priority, if needed.
|
||||
if ( isNaN( priority ) )
|
||||
priority = 10;
|
||||
|
||||
listenerFirer.fn = listenerFunction;
|
||||
listenerFirer.priority = priority;
|
||||
|
||||
// Search for the right position for this new listener, based on its
|
||||
// priority.
|
||||
for ( var i = listeners.length - 1; i >= 0; i-- ) {
|
||||
// Find the item which should be before the new one.
|
||||
if ( listeners[ i ].priority <= priority ) {
|
||||
// Insert the listener in the array.
|
||||
listeners.splice( i + 1, 0, listenerFirer );
|
||||
return { removeListener: removeListener };
|
||||
}
|
||||
}
|
||||
|
||||
// If no position has been found (or zero length), put it in
|
||||
// the front of list.
|
||||
listeners.unshift( listenerFirer );
|
||||
}
|
||||
|
||||
return { removeListener: removeListener };
|
||||
},
|
||||
|
||||
/**
|
||||
* Similiar with {@link #on} but the listener will be called only once upon the next event firing.
|
||||
*
|
||||
* @see CKEDITOR.event#on
|
||||
*/
|
||||
once: function() {
|
||||
var args = Array.prototype.slice.call( arguments ),
|
||||
fn = args[ 1 ];
|
||||
|
||||
args[ 1 ] = function( evt ) {
|
||||
evt.removeListener();
|
||||
return fn.apply( this, arguments );
|
||||
};
|
||||
|
||||
return this.on.apply( this, args );
|
||||
},
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @property {Boolean} useCapture
|
||||
* @todo
|
||||
*/
|
||||
|
||||
/**
|
||||
* Register event handler under the capturing stage on supported target.
|
||||
*/
|
||||
capture: function() {
|
||||
CKEDITOR.event.useCapture = 1;
|
||||
var retval = this.on.apply( this, arguments );
|
||||
CKEDITOR.event.useCapture = 0;
|
||||
return retval;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fires an specific event in the object. All registered listeners are
|
||||
* called at this point.
|
||||
*
|
||||
* someObject.on( 'someEvent', function() { ... } );
|
||||
* someObject.on( 'someEvent', function() { ... } );
|
||||
* someObject.fire( 'someEvent' ); // Both listeners are called.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.data ); // 'Example'
|
||||
* } );
|
||||
* someObject.fire( 'someEvent', 'Example' );
|
||||
*
|
||||
* @method
|
||||
* @param {String} eventName The event name to fire.
|
||||
* @param {Object} [data] Data to be sent as the
|
||||
* {@link CKEDITOR.eventInfo#data} when calling the listeners.
|
||||
* @param {CKEDITOR.editor} [editor] The editor instance to send as the
|
||||
* {@link CKEDITOR.eventInfo#editor} when calling the listener.
|
||||
* @returns {Boolean/Object} A boolean indicating that the event is to be
|
||||
* canceled, or data returned by one of the listeners.
|
||||
*/
|
||||
fire: ( function() {
|
||||
// Create the function that marks the event as stopped.
|
||||
var stopped = 0;
|
||||
var stopEvent = function() {
|
||||
stopped = 1;
|
||||
};
|
||||
|
||||
// Create the function that marks the event as canceled.
|
||||
var canceled = 0;
|
||||
var cancelEvent = function() {
|
||||
canceled = 1;
|
||||
};
|
||||
|
||||
return function( eventName, data, editor ) {
|
||||
// Get the event entry.
|
||||
var event = getPrivate( this )[ eventName ];
|
||||
|
||||
// Save the previous stopped and cancelled states. We may
|
||||
// be nesting fire() calls.
|
||||
var previousStopped = stopped,
|
||||
previousCancelled = canceled;
|
||||
|
||||
// Reset the stopped and canceled flags.
|
||||
stopped = canceled = 0;
|
||||
|
||||
if ( event ) {
|
||||
var listeners = event.listeners;
|
||||
|
||||
if ( listeners.length ) {
|
||||
// As some listeners may remove themselves from the
|
||||
// event, the original array length is dinamic. So,
|
||||
// let's make a copy of all listeners, so we are
|
||||
// sure we'll call all of them.
|
||||
listeners = listeners.slice( 0 );
|
||||
|
||||
var retData;
|
||||
// Loop through all listeners.
|
||||
for ( var i = 0; i < listeners.length; i++ ) {
|
||||
// Call the listener, passing the event data.
|
||||
if ( event.errorProof ) {
|
||||
try {
|
||||
retData = listeners[ i ].call( this, editor, data, stopEvent, cancelEvent );
|
||||
} catch ( er ) {}
|
||||
} else {
|
||||
retData = listeners[ i ].call( this, editor, data, stopEvent, cancelEvent );
|
||||
}
|
||||
|
||||
if ( retData === EVENT_CANCELED )
|
||||
canceled = 1;
|
||||
else if ( typeof retData != 'undefined' )
|
||||
data = retData;
|
||||
|
||||
// No further calls is stopped or canceled.
|
||||
if ( stopped || canceled )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ret = canceled ? false : ( typeof data == 'undefined' ? true : data );
|
||||
|
||||
// Restore the previous stopped and canceled states.
|
||||
stopped = previousStopped;
|
||||
canceled = previousCancelled;
|
||||
|
||||
return ret;
|
||||
};
|
||||
} )(),
|
||||
|
||||
/**
|
||||
* Fires an specific event in the object, releasing all listeners
|
||||
* registered to that event. The same listeners are not called again on
|
||||
* successive calls of it or of {@link #fire}.
|
||||
*
|
||||
* someObject.on( 'someEvent', function() { ... } );
|
||||
* someObject.fire( 'someEvent' ); // Above listener called.
|
||||
* someObject.fireOnce( 'someEvent' ); // Above listener called.
|
||||
* someObject.fire( 'someEvent' ); // No listeners called.
|
||||
*
|
||||
* @param {String} eventName The event name to fire.
|
||||
* @param {Object} [data] Data to be sent as the
|
||||
* {@link CKEDITOR.eventInfo#data} when calling the listeners.
|
||||
* @param {CKEDITOR.editor} [editor] The editor instance to send as the
|
||||
* {@link CKEDITOR.eventInfo#editor} when calling the listener.
|
||||
* @returns {Boolean/Object} A booloan indicating that the event is to be
|
||||
* canceled, or data returned by one of the listeners.
|
||||
*/
|
||||
fireOnce: function( eventName, data, editor ) {
|
||||
var ret = this.fire( eventName, data, editor );
|
||||
delete getPrivate( this )[ eventName ];
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* Unregisters a listener function from being called at the specified
|
||||
* event. No errors are thrown if the listener has not been registered previously.
|
||||
*
|
||||
* var myListener = function() { ... };
|
||||
* someObject.on( 'someEvent', myListener );
|
||||
* someObject.fire( 'someEvent' ); // myListener called.
|
||||
* someObject.removeListener( 'someEvent', myListener );
|
||||
* someObject.fire( 'someEvent' ); // myListener not called.
|
||||
*
|
||||
* @param {String} eventName The event name.
|
||||
* @param {Function} listenerFunction The listener function to unregister.
|
||||
*/
|
||||
removeListener: function( eventName, listenerFunction ) {
|
||||
// Get the event entry.
|
||||
var event = getPrivate( this )[ eventName ];
|
||||
|
||||
if ( event ) {
|
||||
var index = event.getListenerIndex( listenerFunction );
|
||||
if ( index >= 0 )
|
||||
event.listeners.splice( index, 1 );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all existing listeners on this object, for cleanup purpose.
|
||||
*/
|
||||
removeAllListeners: function() {
|
||||
var events = getPrivate( this );
|
||||
for ( var i in events )
|
||||
delete events[ i ];
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if there is any listener registered to a given event.
|
||||
*
|
||||
* var myListener = function() { ... };
|
||||
* someObject.on( 'someEvent', myListener );
|
||||
* alert( someObject.hasListeners( 'someEvent' ) ); // true
|
||||
* alert( someObject.hasListeners( 'noEvent' ) ); // false
|
||||
*
|
||||
* @param {String} eventName The event name.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasListeners: function( eventName ) {
|
||||
var event = getPrivate( this )[ eventName ];
|
||||
return ( event && event.listeners.length > 0 );
|
||||
}
|
||||
};
|
||||
} )();
|
||||
}
|
||||
} )();
|
||||
115
Admin/plugins/ckeditor/core/eventInfo.js
Normal file
115
Admin/plugins/ckeditor/core/eventInfo.js
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.eventInfo} class, which
|
||||
* contains the defintions of the event object passed to event listeners.
|
||||
* This file is for documentation purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Virtual class that illustrates the features of the event object to be
|
||||
* passed to event listeners by a {@link CKEDITOR.event} based object.
|
||||
*
|
||||
* This class is not really part of the API.
|
||||
*
|
||||
* @class CKEDITOR.eventInfo
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* The event name.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.name ); // 'someEvent'
|
||||
* } );
|
||||
* someObject.fire( 'someEvent' );
|
||||
*
|
||||
* @property {String} name
|
||||
*/
|
||||
|
||||
/**
|
||||
* The object that publishes (sends) the event.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.sender == someObject ); // true
|
||||
* } );
|
||||
* someObject.fire( 'someEvent' );
|
||||
*
|
||||
* @property sender
|
||||
*/
|
||||
|
||||
/**
|
||||
* The editor instance that holds the sender. May be the same as sender. May be
|
||||
* null if the sender is not part of an editor instance, like a component
|
||||
* running in standalone mode.
|
||||
*
|
||||
* myButton.on( 'someEvent', function( event ) {
|
||||
* alert( event.editor == myEditor ); // true
|
||||
* } );
|
||||
* myButton.fire( 'someEvent', null, myEditor );
|
||||
*
|
||||
* @property {CKEDITOR.editor} editor
|
||||
*/
|
||||
|
||||
/**
|
||||
* Any kind of additional data. Its format and usage is event dependent.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.data ); // 'Example'
|
||||
* } );
|
||||
* someObject.fire( 'someEvent', 'Example' );
|
||||
*
|
||||
* @property data
|
||||
*/
|
||||
|
||||
/**
|
||||
* Any extra data appended during the listener registration.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.listenerData ); // 'Example'
|
||||
* }, null, 'Example' );
|
||||
*
|
||||
* @property listenerData
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that no further listeners are to be called.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* event.stop();
|
||||
* } );
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* // This one will not be called.
|
||||
* } );
|
||||
* alert( someObject.fire( 'someEvent' ) ); // true
|
||||
*
|
||||
* @method stop
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that the event is to be cancelled (if cancelable).
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* event.cancel();
|
||||
* } );
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* // This one will not be called.
|
||||
* } );
|
||||
* alert( someObject.fire( 'someEvent' ) ); // false
|
||||
*
|
||||
* @method cancel
|
||||
*/
|
||||
|
||||
/**
|
||||
* Removes the current listener.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* event.removeListener();
|
||||
* // Now this function won't be called again by 'someEvent'.
|
||||
* } );
|
||||
*
|
||||
* @method removeListener
|
||||
*/
|
||||
2584
Admin/plugins/ckeditor/core/filter.js
Normal file
2584
Admin/plugins/ckeditor/core/filter.js
Normal file
File diff suppressed because it is too large
Load Diff
275
Admin/plugins/ckeditor/core/focusmanager.js
Normal file
275
Admin/plugins/ckeditor/core/focusmanager.js
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.focusManager} class, which is used
|
||||
* to handle the focus in editor instances.
|
||||
*/
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Manages the focus activity in an editor instance. This class is to be
|
||||
* used mainly by UI element coders when adding interface elements that need
|
||||
* to set the focus state of the editor.
|
||||
*
|
||||
* var focusManager = new CKEDITOR.focusManager( editor );
|
||||
* focusManager.focus();
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a focusManager class instance.
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
*/
|
||||
CKEDITOR.focusManager = function( editor ) {
|
||||
if ( editor.focusManager )
|
||||
return editor.focusManager;
|
||||
|
||||
/**
|
||||
* Indicates that the editor instance has focus.
|
||||
*
|
||||
* alert( CKEDITOR.instances.editor1.focusManager.hasFocus ); // e.g. true
|
||||
*/
|
||||
this.hasFocus = false;
|
||||
|
||||
/**
|
||||
* Indicates the currently focused DOM element that makes the editor activated.
|
||||
*
|
||||
* @property {CKEDITOR.dom.domObject}
|
||||
*/
|
||||
this.currentActive = null;
|
||||
|
||||
/**
|
||||
* Object used to store private stuff.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
this._ = {
|
||||
editor: editor
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
var SLOT_NAME = 'focusmanager',
|
||||
SLOT_NAME_LISTENERS = 'focusmanager_handlers';
|
||||
|
||||
/**
|
||||
* Object used to store private stuff.
|
||||
*
|
||||
* @private
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.focusManager._ = {
|
||||
/**
|
||||
* The delay (in milliseconds) to deactivate the editor when a UI DOM element has lost focus.
|
||||
*
|
||||
* @private
|
||||
* @property {Number} [blurDelay=200]
|
||||
* @member CKEDITOR.focusManager._
|
||||
*/
|
||||
blurDelay: 200
|
||||
};
|
||||
|
||||
CKEDITOR.focusManager.prototype = {
|
||||
|
||||
/**
|
||||
* Indicates that this editor instance is activated (due to a DOM focus change).
|
||||
* The `activated` state is a symbolic indicator of an active user
|
||||
* interaction session.
|
||||
*
|
||||
* **Note:** This method will not introduce UI focus
|
||||
* impact on DOM, it is here to record the editor UI focus state internally.
|
||||
* If you want to make the cursor blink inside the editable, use
|
||||
* {@link CKEDITOR.editor#method-focus} instead.
|
||||
*
|
||||
* var editor = CKEDITOR.instances.editor1;
|
||||
* editor.focusManager.focus( editor.editable() );
|
||||
*
|
||||
* @param {CKEDITOR.dom.element} [currentActive] The new value of the {@link #currentActive} property.
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
focus: function( currentActive ) {
|
||||
if ( this._.timer )
|
||||
clearTimeout( this._.timer );
|
||||
|
||||
if ( currentActive )
|
||||
this.currentActive = currentActive;
|
||||
|
||||
if ( !( this.hasFocus || this._.locked ) ) {
|
||||
// If another editor has the current focus, we first "blur" it. In
|
||||
// this way the events happen in a more logical sequence, like:
|
||||
// "focus 1" > "blur 1" > "focus 2"
|
||||
// ... instead of:
|
||||
// "focus 1" > "focus 2" > "blur 1"
|
||||
var current = CKEDITOR.currentInstance;
|
||||
current && current.focusManager.blur( 1 );
|
||||
|
||||
this.hasFocus = true;
|
||||
|
||||
var ct = this._.editor.container;
|
||||
ct && ct.addClass( 'cke_focus' );
|
||||
this._.editor.fire( 'focus' );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Prevents from changing the focus manager state until the next {@link #unlock} is called.
|
||||
*
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
lock: function() {
|
||||
this._.locked = 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Restores the automatic focus management if {@link #lock} is called.
|
||||
*
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
unlock: function() {
|
||||
delete this._.locked;
|
||||
},
|
||||
|
||||
/**
|
||||
* Used to indicate that the editor instance has been deactivated by the specified
|
||||
* element which has just lost focus.
|
||||
*
|
||||
* **Note:** This function acts asynchronously with a delay of 100ms to
|
||||
* avoid temporary deactivation. Use the `noDelay` parameter instead
|
||||
* to deactivate immediately.
|
||||
*
|
||||
* var editor = CKEDITOR.instances.editor1;
|
||||
* editor.focusManager.blur();
|
||||
*
|
||||
* @param {Boolean} [noDelay=false] Immediately deactivate the editor instance synchronously.
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
blur: function( noDelay ) {
|
||||
if ( this._.locked ) {
|
||||
return;
|
||||
}
|
||||
|
||||
function doBlur() {
|
||||
if ( this.hasFocus ) {
|
||||
this.hasFocus = false;
|
||||
|
||||
var ct = this._.editor.container;
|
||||
ct && ct.removeClass( 'cke_focus' );
|
||||
this._.editor.fire( 'blur' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( this._.timer ) {
|
||||
clearTimeout( this._.timer );
|
||||
}
|
||||
|
||||
var delay = CKEDITOR.focusManager._.blurDelay;
|
||||
if ( noDelay || !delay ) {
|
||||
doBlur.call( this );
|
||||
} else {
|
||||
this._.timer = CKEDITOR.tools.setTimeout( function() {
|
||||
delete this._.timer;
|
||||
doBlur.call( this );
|
||||
}, delay, this );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a UI DOM element to the focus manager, which will make the focus manager "hasFocus"
|
||||
* once the input focus is relieved on the element.
|
||||
* This method is designed to be used by plugins to expand the jurisdiction of the editor focus.
|
||||
*
|
||||
* @param {CKEDITOR.dom.element} element The container (topmost) element of one UI part.
|
||||
* @param {Boolean} isCapture If specified, {@link CKEDITOR.event#useCapture} will be used when listening to the focus event.
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
add: function( element, isCapture ) {
|
||||
var fm = element.getCustomData( SLOT_NAME );
|
||||
if ( !fm || fm != this ) {
|
||||
// If this element is already taken by another instance, dismiss it first.
|
||||
fm && fm.remove( element );
|
||||
|
||||
var focusEvent = 'focus',
|
||||
blurEvent = 'blur';
|
||||
|
||||
// Bypass the element's internal DOM focus change.
|
||||
if ( isCapture ) {
|
||||
|
||||
// Use "focusin/focusout" events instead of capture phase in IEs,
|
||||
// which fires synchronously.
|
||||
if ( CKEDITOR.env.ie ) {
|
||||
focusEvent = 'focusin';
|
||||
blurEvent = 'focusout';
|
||||
} else {
|
||||
CKEDITOR.event.useCapture = 1;
|
||||
}
|
||||
}
|
||||
|
||||
var listeners = {
|
||||
blur: function() {
|
||||
if ( element.equals( this.currentActive ) )
|
||||
this.blur();
|
||||
},
|
||||
focus: function() {
|
||||
this.focus( element );
|
||||
}
|
||||
};
|
||||
|
||||
element.on( focusEvent, listeners.focus, this );
|
||||
element.on( blurEvent, listeners.blur, this );
|
||||
|
||||
if ( isCapture )
|
||||
CKEDITOR.event.useCapture = 0;
|
||||
|
||||
element.setCustomData( SLOT_NAME, this );
|
||||
element.setCustomData( SLOT_NAME_LISTENERS, listeners );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Dismisses an element from the focus manager delegations added by {@link #add}.
|
||||
*
|
||||
* @param {CKEDITOR.dom.element} element The element to be removed from the focus manager.
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
remove: function( element ) {
|
||||
element.removeCustomData( SLOT_NAME );
|
||||
var listeners = element.removeCustomData( SLOT_NAME_LISTENERS );
|
||||
element.removeListener( 'blur', listeners.blur );
|
||||
element.removeListener( 'focus', listeners.focus );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} )();
|
||||
|
||||
/**
|
||||
* Fired when the editor instance receives the input focus.
|
||||
*
|
||||
* editor.on( 'focus', function( e ) {
|
||||
* alert( 'The editor named ' + e.editor.name + ' is now focused' );
|
||||
* } );
|
||||
*
|
||||
* @event focus
|
||||
* @member CKEDITOR.editor
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the editor instance loses the input focus.
|
||||
*
|
||||
* **Note:** This event will **NOT** be triggered when focus is moved internally, e.g. from
|
||||
* an editable to another part of the editor UI like a dialog window.
|
||||
* If you are interested only in the focus state of the editable, listen to the `focus`
|
||||
* and `blur` events of the {@link CKEDITOR.editable} instead.
|
||||
*
|
||||
* editor.on( 'blur', function( e ) {
|
||||
* alert( 'The editor named ' + e.editor.name + ' lost the focus' );
|
||||
* } );
|
||||
*
|
||||
* @event blur
|
||||
* @member CKEDITOR.editor
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
*/
|
||||
1218
Admin/plugins/ckeditor/core/htmldataprocessor.js
Normal file
1218
Admin/plugins/ckeditor/core/htmldataprocessor.js
Normal file
File diff suppressed because it is too large
Load Diff
205
Admin/plugins/ckeditor/core/htmlparser.js
Normal file
205
Admin/plugins/ckeditor/core/htmlparser.js
Normal file
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides an "event like" system to parse strings of HTML data.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onTagOpen = function( tagName, attributes, selfClosing ) {
|
||||
* alert( tagName );
|
||||
* };
|
||||
* parser.parse( '<p>Some <b>text</b>.</p>' ); // Alerts 'p', 'b'.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a htmlParser class instance.
|
||||
*/
|
||||
CKEDITOR.htmlParser = function() {
|
||||
this._ = {
|
||||
htmlPartsRegex: /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)--!?>)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))/g
|
||||
};
|
||||
};
|
||||
|
||||
( function() {
|
||||
var attribsRegex = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,
|
||||
emptyAttribs = { checked: 1, compact: 1, declare: 1, defer: 1, disabled: 1, ismap: 1, multiple: 1, nohref: 1, noresize: 1, noshade: 1, nowrap: 1, readonly: 1, selected: 1 };
|
||||
|
||||
CKEDITOR.htmlParser.prototype = {
|
||||
/**
|
||||
* Function to be fired when a tag opener is found. This function
|
||||
* should be overriden when using this class.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onTagOpen = function( tagName, attributes, selfClosing ) {
|
||||
* alert( tagName ); // e.g. 'b'
|
||||
* } );
|
||||
* parser.parse( '<!-- Example --><b>Hello</b>' );
|
||||
*
|
||||
* @param {String} tagName The tag name. The name is guarantted to be lowercased.
|
||||
* @param {Object} attributes An object containing all tag attributes. Each
|
||||
* property in this object represent and attribute name and its value is the attribute value.
|
||||
* @param {Boolean} selfClosing `true` if the tag closes itself, false if the tag doesn't.
|
||||
*/
|
||||
onTagOpen: function() {},
|
||||
|
||||
/**
|
||||
* Function to be fired when a tag closer is found. This function
|
||||
* should be overriden when using this class.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onTagClose = function( tagName ) {
|
||||
* alert( tagName ); // 'b'
|
||||
* } );
|
||||
* parser.parse( '<!-- Example --><b>Hello</b>' );
|
||||
*
|
||||
* @param {String} tagName The tag name. The name is guarantted to be lowercased.
|
||||
*/
|
||||
onTagClose: function() {},
|
||||
|
||||
/**
|
||||
* Function to be fired when text is found. This function
|
||||
* should be overriden when using this class.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onText = function( text ) {
|
||||
* alert( text ); // 'Hello'
|
||||
* } );
|
||||
* parser.parse( '<!-- Example --><b>Hello</b>' );
|
||||
*
|
||||
* @param {String} text The text found.
|
||||
*/
|
||||
onText: function() {},
|
||||
|
||||
/**
|
||||
* Function to be fired when CDATA section is found. This function
|
||||
* should be overriden when using this class.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onCDATA = function( cdata ) {
|
||||
* alert( cdata ); // 'var hello;'
|
||||
* } );
|
||||
* parser.parse( '<script>var hello;</script>' );
|
||||
*
|
||||
* @param {String} cdata The CDATA been found.
|
||||
*/
|
||||
onCDATA: function() {},
|
||||
|
||||
/**
|
||||
* Function to be fired when a commend is found. This function
|
||||
* should be overriden when using this class.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onComment = function( comment ) {
|
||||
* alert( comment ); // ' Example '
|
||||
* } );
|
||||
* parser.parse( '<!-- Example --><b>Hello</b>' );
|
||||
*
|
||||
* @param {String} comment The comment text.
|
||||
*/
|
||||
onComment: function() {},
|
||||
|
||||
/**
|
||||
* Parses text, looking for HTML tokens, like tag openers or closers,
|
||||
* or comments. This function fires the onTagOpen, onTagClose, onText
|
||||
* and onComment function during its execution.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* // The onTagOpen, onTagClose, onText and onComment should be overriden
|
||||
* // at this point.
|
||||
* parser.parse( '<!-- Example --><b>Hello</b>' );
|
||||
*
|
||||
* @param {String} html The HTML to be parsed.
|
||||
*/
|
||||
parse: function( html ) {
|
||||
var parts, tagName,
|
||||
nextIndex = 0,
|
||||
cdata; // The collected data inside a CDATA section.
|
||||
|
||||
while ( ( parts = this._.htmlPartsRegex.exec( html ) ) ) {
|
||||
var tagIndex = parts.index;
|
||||
if ( tagIndex > nextIndex ) {
|
||||
var text = html.substring( nextIndex, tagIndex );
|
||||
|
||||
if ( cdata )
|
||||
cdata.push( text );
|
||||
else
|
||||
this.onText( text );
|
||||
}
|
||||
|
||||
nextIndex = this._.htmlPartsRegex.lastIndex;
|
||||
|
||||
// "parts" is an array with the following items:
|
||||
// 0 : The entire match for opening/closing tags and comments.
|
||||
// : Group filled with the tag name for closing tags.
|
||||
// 2 : Group filled with the comment text.
|
||||
// 3 : Group filled with the tag name for opening tags.
|
||||
// 4 : Group filled with the attributes part of opening tags.
|
||||
|
||||
// Closing tag
|
||||
if ( ( tagName = parts[ 1 ] ) ) {
|
||||
tagName = tagName.toLowerCase();
|
||||
|
||||
if ( cdata && CKEDITOR.dtd.$cdata[ tagName ] ) {
|
||||
// Send the CDATA data.
|
||||
this.onCDATA( cdata.join( '' ) );
|
||||
cdata = null;
|
||||
}
|
||||
|
||||
if ( !cdata ) {
|
||||
this.onTagClose( tagName );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If CDATA is enabled, just save the raw match.
|
||||
if ( cdata ) {
|
||||
cdata.push( parts[ 0 ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Opening tag
|
||||
if ( ( tagName = parts[ 3 ] ) ) {
|
||||
tagName = tagName.toLowerCase();
|
||||
|
||||
// There are some tag names that can break things, so let's
|
||||
// simply ignore them when parsing. (https://dev.ckeditor.com/ticket/5224)
|
||||
if ( /="/.test( tagName ) )
|
||||
continue;
|
||||
|
||||
var attribs = {},
|
||||
attribMatch,
|
||||
attribsPart = parts[ 4 ],
|
||||
selfClosing = !!parts[ 5 ];
|
||||
|
||||
if ( attribsPart ) {
|
||||
while ( ( attribMatch = attribsRegex.exec( attribsPart ) ) ) {
|
||||
var attName = attribMatch[ 1 ].toLowerCase(),
|
||||
attValue = attribMatch[ 2 ] || attribMatch[ 3 ] || attribMatch[ 4 ] || '';
|
||||
|
||||
if ( !attValue && emptyAttribs[ attName ] )
|
||||
attribs[ attName ] = attName;
|
||||
else
|
||||
attribs[ attName ] = CKEDITOR.tools.htmlDecodeAttr( attValue );
|
||||
}
|
||||
}
|
||||
|
||||
this.onTagOpen( tagName, attribs, selfClosing );
|
||||
|
||||
// Open CDATA mode when finding the appropriate tags.
|
||||
if ( !cdata && CKEDITOR.dtd.$cdata[ tagName ] )
|
||||
cdata = [];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Comment
|
||||
if ( ( tagName = parts[ 2 ] ) )
|
||||
this.onComment( tagName );
|
||||
}
|
||||
|
||||
if ( html.length > nextIndex )
|
||||
this.onText( html.substring( nextIndex, html.length ) );
|
||||
}
|
||||
};
|
||||
} )();
|
||||
152
Admin/plugins/ckeditor/core/htmlparser/basicwriter.js
Normal file
152
Admin/plugins/ckeditor/core/htmlparser/basicwriter.js
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @class
|
||||
* @todo
|
||||
*/
|
||||
CKEDITOR.htmlParser.basicWriter = CKEDITOR.tools.createClass( {
|
||||
/**
|
||||
* Creates a basicWriter class instance.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
$: function() {
|
||||
this._ = {
|
||||
output: []
|
||||
};
|
||||
},
|
||||
|
||||
proto: {
|
||||
/**
|
||||
* Writes the tag opening part for a opener tag.
|
||||
*
|
||||
* // Writes '<p'.
|
||||
* writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } );
|
||||
*
|
||||
* @param {String} tagName The element name for this tag.
|
||||
* @param {Object} attributes The attributes defined for this tag. The
|
||||
* attributes could be used to inspect the tag.
|
||||
*/
|
||||
openTag: function( tagName ) {
|
||||
this._.output.push( '<', tagName );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the tag closing part for a opener tag.
|
||||
*
|
||||
* // Writes '>'.
|
||||
* writer.openTagClose( 'p', false );
|
||||
*
|
||||
* // Writes ' />'.
|
||||
* writer.openTagClose( 'br', true );
|
||||
*
|
||||
* @param {String} tagName The element name for this tag.
|
||||
* @param {Boolean} isSelfClose Indicates that this is a self-closing tag,
|
||||
* like `<br>` or `<img>`.
|
||||
*/
|
||||
openTagClose: function( tagName, isSelfClose ) {
|
||||
if ( isSelfClose )
|
||||
this._.output.push( ' />' );
|
||||
else
|
||||
this._.output.push( '>' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes an attribute. This function should be called after opening the
|
||||
* tag with {@link #openTagClose}.
|
||||
*
|
||||
* // Writes ' class="MyClass"'.
|
||||
* writer.attribute( 'class', 'MyClass' );
|
||||
*
|
||||
* @param {String} attName The attribute name.
|
||||
* @param {String} attValue The attribute value.
|
||||
*/
|
||||
attribute: function( attName, attValue ) {
|
||||
// Browsers don't always escape special character in attribute values. (https://dev.ckeditor.com/ticket/4683, https://dev.ckeditor.com/ticket/4719).
|
||||
if ( typeof attValue == 'string' )
|
||||
attValue = CKEDITOR.tools.htmlEncodeAttr( attValue );
|
||||
|
||||
this._.output.push( ' ', attName, '="', attValue, '"' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes a closer tag.
|
||||
*
|
||||
* // Writes '</p>'.
|
||||
* writer.closeTag( 'p' );
|
||||
*
|
||||
* @param {String} tagName The element name for this tag.
|
||||
*/
|
||||
closeTag: function( tagName ) {
|
||||
this._.output.push( '</', tagName, '>' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes text.
|
||||
*
|
||||
* // Writes 'Hello Word'.
|
||||
* writer.text( 'Hello Word' );
|
||||
*
|
||||
* @param {String} text The text value.
|
||||
*/
|
||||
text: function( text ) {
|
||||
this._.output.push( text );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes a comment.
|
||||
*
|
||||
* // Writes '<!-- My comment -->'.
|
||||
* writer.comment( ' My comment ' );
|
||||
*
|
||||
* @param {String} comment The comment text.
|
||||
*/
|
||||
comment: function( comment ) {
|
||||
this._.output.push( '<!--', comment, '-->' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes any kind of data to the ouput.
|
||||
*
|
||||
* writer.write( 'This is an <b>example</b>.' );
|
||||
*
|
||||
* @param {String} data
|
||||
*/
|
||||
write: function( data ) {
|
||||
this._.output.push( data );
|
||||
},
|
||||
|
||||
/**
|
||||
* Empties the current output buffer.
|
||||
*
|
||||
* writer.reset();
|
||||
*/
|
||||
reset: function() {
|
||||
this._.output = [];
|
||||
this._.indent = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Empties the current output buffer.
|
||||
*
|
||||
* var html = writer.getHtml();
|
||||
*
|
||||
* @param {Boolean} reset Indicates that the {@link #reset} method is to
|
||||
* be automatically called after retrieving the HTML.
|
||||
* @returns {String} The HTML written to the writer so far.
|
||||
*/
|
||||
getHtml: function( reset ) {
|
||||
var html = this._.output.join( '' );
|
||||
|
||||
if ( reset )
|
||||
this.reset();
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
} );
|
||||
70
Admin/plugins/ckeditor/core/htmlparser/cdata.js
Normal file
70
Admin/plugins/ckeditor/core/htmlparser/cdata.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
|
||||
/**
|
||||
* A lightweight representation of HTML CDATA.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.htmlParser.node
|
||||
* @constructor Creates a cdata class instance.
|
||||
* @param {String} value The CDATA section value.
|
||||
*/
|
||||
CKEDITOR.htmlParser.cdata = function( value ) {
|
||||
/**
|
||||
* The CDATA value.
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
this.value = value;
|
||||
};
|
||||
|
||||
CKEDITOR.htmlParser.cdata.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
|
||||
/**
|
||||
* CDATA has the same type as {@link CKEDITOR.htmlParser.text} This is
|
||||
* a constant value set to {@link CKEDITOR#NODE_TEXT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_TEXT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_TEXT,
|
||||
|
||||
filter: function( filter ) {
|
||||
var style = this.getAscendant( 'style' );
|
||||
|
||||
if ( !style ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// MathML and SVG namespaces processing parsers `style` content as a normal HTML, not text.
|
||||
// Make sure to filter such content also.
|
||||
var nonHtmlElementNamespace = style.getAscendant( { math: 1, svg: 1 } );
|
||||
|
||||
if ( !nonHtmlElementNamespace ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var fragment = CKEDITOR.htmlParser.fragment.fromHtml( this.value ),
|
||||
writer = new CKEDITOR.htmlParser.basicWriter();
|
||||
|
||||
filter.applyTo( fragment );
|
||||
fragment.writeHtml( writer );
|
||||
|
||||
this.value = writer.getHtml();
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the CDATA with no special manipulations.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
|
||||
*/
|
||||
writeHtml: function( writer ) {
|
||||
writer.write( this.value );
|
||||
}
|
||||
} );
|
||||
} )();
|
||||
80
Admin/plugins/ckeditor/core/htmlparser/comment.js
Normal file
80
Admin/plugins/ckeditor/core/htmlparser/comment.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A lightweight representation of an HTML comment.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.htmlParser.node
|
||||
* @constructor Creates a comment class instance.
|
||||
* @param {String} value The comment text value.
|
||||
*/
|
||||
CKEDITOR.htmlParser.comment = function( value ) {
|
||||
/**
|
||||
* The comment text.
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
this.value = value;
|
||||
|
||||
/** @private */
|
||||
this._ = {
|
||||
isBlockLike: false
|
||||
};
|
||||
};
|
||||
|
||||
CKEDITOR.htmlParser.comment.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_COMMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_COMMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_COMMENT,
|
||||
|
||||
/**
|
||||
* Filter this comment with given filter.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
* @returns {Boolean} Method returns `false` when this comment has
|
||||
* been removed or replaced with other node. This is an information for
|
||||
* {@link CKEDITOR.htmlParser.element#filterChildren} that it has
|
||||
* to repeat filter on current position in parent's children array.
|
||||
*/
|
||||
filter: function( filter, context ) {
|
||||
var comment = this.value;
|
||||
|
||||
if ( !( comment = filter.onComment( context, comment, this ) ) ) {
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( typeof comment != 'string' ) {
|
||||
this.replaceWith( comment );
|
||||
return false;
|
||||
}
|
||||
|
||||
this.value = comment;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the HTML representation of this comment to a CKEDITOR.htmlWriter.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
|
||||
* **Note:** it's unsafe to filter offline (not appended) node.
|
||||
*/
|
||||
writeHtml: function( writer, filter ) {
|
||||
if ( filter )
|
||||
this.filter( filter );
|
||||
|
||||
writer.comment( this.value );
|
||||
}
|
||||
} );
|
||||
593
Admin/plugins/ckeditor/core/htmlparser/element.js
Normal file
593
Admin/plugins/ckeditor/core/htmlparser/element.js
Normal file
@@ -0,0 +1,593 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A lightweight representation of an HTML element.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.htmlParser.node
|
||||
* @constructor Creates an element class instance.
|
||||
* @param {String} name The element name.
|
||||
* @param {Object} attributes An object storing all attributes defined for
|
||||
* this element.
|
||||
*/
|
||||
CKEDITOR.htmlParser.element = function( name, attributes ) {
|
||||
/**
|
||||
* The element name.
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
this.name = name;
|
||||
|
||||
/**
|
||||
* Stores the attributes defined for this element.
|
||||
*
|
||||
* @property {Object}
|
||||
*/
|
||||
this.attributes = attributes || {};
|
||||
|
||||
/**
|
||||
* The nodes that are direct children of this element.
|
||||
*/
|
||||
this.children = [];
|
||||
|
||||
// Reveal the real semantic of our internal custom tag name (https://dev.ckeditor.com/ticket/6639),
|
||||
// when resolving whether it's block like.
|
||||
var realName = name || '',
|
||||
prefixed = realName.match( /^cke:(.*)/ );
|
||||
prefixed && ( realName = prefixed[ 1 ] );
|
||||
|
||||
var isBlockLike = !!( CKEDITOR.dtd.$nonBodyContent[ realName ] || CKEDITOR.dtd.$block[ realName ] ||
|
||||
CKEDITOR.dtd.$listItem[ realName ] || CKEDITOR.dtd.$tableContent[ realName ] ||
|
||||
CKEDITOR.dtd.$nonEditable[ realName ] || realName == 'br' );
|
||||
|
||||
this.isEmpty = !!CKEDITOR.dtd.$empty[ name ];
|
||||
this.isUnknown = !CKEDITOR.dtd[ name ];
|
||||
|
||||
/** @private */
|
||||
this._ = {
|
||||
isBlockLike: isBlockLike,
|
||||
hasInlineStarted: this.isEmpty || !isBlockLike
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Object presentation of the CSS style declaration text.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a `cssStyle` class instance.
|
||||
* @param {CKEDITOR.htmlParser.element/String} elementOrStyleText
|
||||
* An HTML parser element or the inline style text.
|
||||
*/
|
||||
CKEDITOR.htmlParser.cssStyle = function() {
|
||||
var styleText,
|
||||
arg = arguments[ 0 ],
|
||||
rules = {};
|
||||
|
||||
styleText = arg instanceof CKEDITOR.htmlParser.element ? arg.attributes.style : arg;
|
||||
|
||||
// html-encoded quote might be introduced by 'font-family'
|
||||
// from MS-Word which confused the following regexp. e.g.
|
||||
//'font-family: "Lucida, Console"'
|
||||
// TODO reuse CSS methods from tools.
|
||||
( styleText || '' ).replace( /"/g, '"' ).replace( /\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g, function( match, name, value ) {
|
||||
name == 'font-family' && ( value = value.replace( /["']/g, '' ) );
|
||||
rules[ name.toLowerCase() ] = value;
|
||||
} );
|
||||
|
||||
return {
|
||||
|
||||
rules: rules,
|
||||
|
||||
/**
|
||||
* Applies the styles to the specified element or object.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.element/CKEDITOR.dom.element/Object} obj
|
||||
*/
|
||||
populate: function( obj ) {
|
||||
var style = this.toString();
|
||||
if ( style )
|
||||
obj instanceof CKEDITOR.dom.element ? obj.setAttribute( 'style', style ) : obj instanceof CKEDITOR.htmlParser.element ? obj.attributes.style = style : obj.style = style;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Serializes CSS style declaration to a string.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
toString: function() {
|
||||
var output = [];
|
||||
for ( var i in rules )
|
||||
rules[ i ] && output.push( i, ':', rules[ i ], ';' );
|
||||
return output.join( '' );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/** @class CKEDITOR.htmlParser.element */
|
||||
( function() {
|
||||
// Used to sort attribute entries in an array, where the first element of
|
||||
// each object is the attribute name.
|
||||
var sortAttribs = function( a, b ) {
|
||||
a = a[ 0 ];
|
||||
b = b[ 0 ];
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
},
|
||||
fragProto = CKEDITOR.htmlParser.fragment.prototype;
|
||||
|
||||
CKEDITOR.htmlParser.element.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_ELEMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_ELEMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_ELEMENT,
|
||||
|
||||
/**
|
||||
* Adds a node to the element children list.
|
||||
*
|
||||
* @method
|
||||
* @param {CKEDITOR.htmlParser.node} node The node to be added.
|
||||
* @param {Number} [index] From where the insertion happens.
|
||||
*/
|
||||
add: fragProto.add,
|
||||
|
||||
/**
|
||||
* Clones this element.
|
||||
*
|
||||
* @returns {CKEDITOR.htmlParser.element} The element clone.
|
||||
*/
|
||||
clone: function() {
|
||||
return new CKEDITOR.htmlParser.element( this.name, this.attributes );
|
||||
},
|
||||
|
||||
/**
|
||||
* Filters this element and its children with the given filter.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
* @returns {Boolean} The method returns `false` when this element has
|
||||
* been removed or replaced with another. This information means that
|
||||
* {@link #filterChildren} has to repeat the filter on the current
|
||||
* position in parent's children array.
|
||||
*/
|
||||
filter: function( filter, context ) {
|
||||
var element = this,
|
||||
originalName, name;
|
||||
|
||||
context = element.getFilterContext( context );
|
||||
|
||||
// Filtering if it's the root node.
|
||||
if ( !element.parent )
|
||||
filter.onRoot( context, element );
|
||||
|
||||
while ( true ) {
|
||||
originalName = element.name;
|
||||
|
||||
if ( !( name = filter.onElementName( context, originalName ) ) ) {
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
element.name = name;
|
||||
|
||||
if ( !( element = filter.onElement( context, element ) ) ) {
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
// New element has been returned - replace current one
|
||||
// and process it (stop processing this and return false, what
|
||||
// means that element has been removed).
|
||||
if ( element !== this ) {
|
||||
this.replaceWith( element );
|
||||
return false;
|
||||
}
|
||||
|
||||
// If name has been changed - continue loop, so in next iteration
|
||||
// filters for new name will be applied to this element.
|
||||
// If name hasn't been changed - stop.
|
||||
if ( element.name == originalName )
|
||||
break;
|
||||
|
||||
// If element has been replaced with something of a
|
||||
// different type, then make the replacement filter itself.
|
||||
if ( element.type != CKEDITOR.NODE_ELEMENT ) {
|
||||
this.replaceWith( element );
|
||||
return false;
|
||||
}
|
||||
|
||||
// This indicate that the element has been dropped by
|
||||
// filter but not the children.
|
||||
if ( !element.name ) {
|
||||
this.replaceWithChildren();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var attributes = element.attributes,
|
||||
a, value, newAttrName;
|
||||
|
||||
for ( a in attributes ) {
|
||||
newAttrName = a;
|
||||
value = attributes[ a ];
|
||||
|
||||
// Loop until name isn't modified.
|
||||
// A little bit senseless, but IE would do that anyway
|
||||
// because it iterates with for-in loop even over properties
|
||||
// created during its run.
|
||||
while ( true ) {
|
||||
if ( !( newAttrName = filter.onAttributeName( context, a ) ) ) {
|
||||
delete attributes[ a ];
|
||||
break;
|
||||
} else if ( newAttrName != a ) {
|
||||
delete attributes[ a ];
|
||||
a = newAttrName;
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( newAttrName ) {
|
||||
if ( ( value = filter.onAttribute( context, element, newAttrName, value ) ) === false )
|
||||
delete attributes[ newAttrName ];
|
||||
else
|
||||
attributes[ newAttrName ] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !element.isEmpty )
|
||||
this.filterChildren( filter, false, context );
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Filters this element's children with the given filter.
|
||||
*
|
||||
* Element's children may only be filtered once by one
|
||||
* instance of the filter.
|
||||
*
|
||||
* @method filterChildren
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
*/
|
||||
filterChildren: fragProto.filterChildren,
|
||||
|
||||
/**
|
||||
* Writes the element HTML to the CKEDITOR.htmlWriter.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which HTML will be written.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
|
||||
* **Note:** It is unsafe to filter an offline (not appended) node.
|
||||
*/
|
||||
writeHtml: function( writer, filter ) {
|
||||
if ( filter )
|
||||
this.filter( filter );
|
||||
|
||||
var name = this.name,
|
||||
attribsArray = [],
|
||||
attributes = this.attributes,
|
||||
attrName,
|
||||
attr, i, l;
|
||||
|
||||
// Open element tag.
|
||||
writer.openTag( name, attributes );
|
||||
|
||||
// Copy all attributes to an array.
|
||||
for ( attrName in attributes )
|
||||
attribsArray.push( [ attrName, attributes[ attrName ] ] );
|
||||
|
||||
// Sort the attributes by name.
|
||||
if ( writer.sortAttributes )
|
||||
attribsArray.sort( sortAttribs );
|
||||
|
||||
// Send the attributes.
|
||||
for ( i = 0, l = attribsArray.length; i < l; i++ ) {
|
||||
attr = attribsArray[ i ];
|
||||
writer.attribute( attr[ 0 ], attr[ 1 ] );
|
||||
}
|
||||
|
||||
// Close the tag.
|
||||
writer.openTagClose( name, this.isEmpty );
|
||||
|
||||
this.writeChildrenHtml( writer );
|
||||
|
||||
// Close the element.
|
||||
if ( !this.isEmpty )
|
||||
writer.closeTag( name );
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends children of this element to the writer.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which HTML will be written.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter]
|
||||
*/
|
||||
writeChildrenHtml: fragProto.writeChildrenHtml,
|
||||
|
||||
/**
|
||||
* Replaces this element with its children.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*/
|
||||
replaceWithChildren: function() {
|
||||
var children = this.children;
|
||||
|
||||
for ( var i = children.length; i; )
|
||||
children[ --i ].insertAfter( this );
|
||||
|
||||
this.remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes a callback on each node (of the given type) in this element.
|
||||
*
|
||||
* // Create a <p> element with foo<b>bar</b>bom as its content.
|
||||
* var elP = CKEDITOR.htmlParser.fragment.fromHtml( 'foo<b>bar</b>bom', 'p' );
|
||||
* elP.forEach( function( node ) {
|
||||
* console.log( node );
|
||||
* } );
|
||||
* // Will log:
|
||||
* // 1. document fragment,
|
||||
* // 2. <p> element,
|
||||
* // 3. "foo" text node,
|
||||
* // 4. <b> element,
|
||||
* // 5. "bar" text node,
|
||||
* // 6. "bom" text node.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {Function} callback Function to be executed on every node.
|
||||
* **Since 4.3**: If `callback` returned `false`, the descendants of the current node will be ignored.
|
||||
* @param {CKEDITOR.htmlParser.node} callback.node Node passed as an argument.
|
||||
* @param {Number} [type] Whether the specified `callback` will be executed only on nodes of this type.
|
||||
* @param {Boolean} [skipRoot] Do not execute `callback` on this element.
|
||||
*/
|
||||
forEach: fragProto.forEach,
|
||||
|
||||
/**
|
||||
* Gets this element's first child. If `condition` is given, this method returns
|
||||
* the first child which satisfies that condition.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String/Object/Function} condition Name of a child, a hash of names, or a validator function.
|
||||
* @returns {CKEDITOR.htmlParser.node}
|
||||
*/
|
||||
getFirst: function( condition ) {
|
||||
if ( !condition )
|
||||
return this.children.length ? this.children[ 0 ] : null;
|
||||
|
||||
if ( typeof condition != 'function' )
|
||||
condition = nameCondition( condition );
|
||||
|
||||
for ( var i = 0, l = this.children.length; i < l; ++i ) {
|
||||
if ( condition( this.children[ i ] ) )
|
||||
return this.children[ i ];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets this element's inner HTML.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @returns {String}
|
||||
*/
|
||||
getHtml: function() {
|
||||
var writer = new CKEDITOR.htmlParser.basicWriter();
|
||||
this.writeChildrenHtml( writer );
|
||||
return writer.getHtml();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets this element's inner HTML.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String} html
|
||||
*/
|
||||
setHtml: function( html ) {
|
||||
var children = this.children = CKEDITOR.htmlParser.fragment.fromHtml( html ).children;
|
||||
|
||||
for ( var i = 0, l = children.length; i < l; ++i )
|
||||
children[ i ].parent = this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets this element's outer HTML.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @returns {String}
|
||||
*/
|
||||
getOuterHtml: function() {
|
||||
var writer = new CKEDITOR.htmlParser.basicWriter();
|
||||
this.writeHtml( writer );
|
||||
return writer.getHtml();
|
||||
},
|
||||
|
||||
/**
|
||||
* Splits this element at the given index.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {Number} index Index at which the element will be split — `0` means the beginning,
|
||||
* `1` after the first child node, etc.
|
||||
* @returns {CKEDITOR.htmlParser.element} The new element following this one.
|
||||
*/
|
||||
split: function( index ) {
|
||||
var cloneChildren = this.children.splice( index, this.children.length - index ),
|
||||
clone = this.clone();
|
||||
|
||||
for ( var i = 0; i < cloneChildren.length; ++i )
|
||||
cloneChildren[ i ].parent = clone;
|
||||
|
||||
clone.children = cloneChildren;
|
||||
|
||||
if ( cloneChildren[ 0 ] )
|
||||
cloneChildren[ 0 ].previous = null;
|
||||
|
||||
if ( index > 0 )
|
||||
this.children[ index - 1 ].next = null;
|
||||
|
||||
this.parent.add( clone, this.getIndex() + 1 );
|
||||
|
||||
return clone;
|
||||
},
|
||||
|
||||
/**
|
||||
* Searches through the current node children to find nodes matching the `criteria`.
|
||||
*
|
||||
* @param {String/Function} criteria Tag name or evaluator function.
|
||||
* @param {Boolean} [recursive=false]
|
||||
* @returns {CKEDITOR.htmlParser.node[]}
|
||||
*/
|
||||
find: function( criteria, recursive ) {
|
||||
if ( recursive === undefined ) {
|
||||
recursive = false;
|
||||
}
|
||||
|
||||
var ret = [],
|
||||
i;
|
||||
|
||||
for ( i = 0; i < this.children.length; i++ ) {
|
||||
var curChild = this.children[ i ];
|
||||
|
||||
if ( typeof criteria == 'function' && criteria( curChild ) ) {
|
||||
ret.push( curChild );
|
||||
} else if ( typeof criteria == 'string' && curChild.name === criteria ) {
|
||||
ret.push( curChild );
|
||||
}
|
||||
|
||||
if ( recursive && curChild.find ) {
|
||||
ret = ret.concat( curChild.find( criteria, recursive ) );
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* Searches through the children of the current element to find the first child matching the `criteria`.
|
||||
*
|
||||
* ```js
|
||||
* element.findOne( function( child ) {
|
||||
* return child.name === 'span' || child.name === 'strong';
|
||||
* } ); // Will return the first child which is a <span> or a <strong> element.
|
||||
* ```
|
||||
*
|
||||
* @param {String/Function} criteria Tag name or evaluator function.
|
||||
* @param {Boolean} [recursive=false] If set to `true`, it will iterate over all descendants. Otherwise the method will
|
||||
* only iterate over direct children.
|
||||
* @returns {CKEDITOR.htmlParser.node/null} The first matched child, `null` otherwise.
|
||||
*/
|
||||
findOne: function( criteria, recursive ) {
|
||||
var nestedMatch = null,
|
||||
match = CKEDITOR.tools.array.find( this.children, function( child ) {
|
||||
var isMatching = typeof criteria === 'function' ? criteria( child ) : child.name === criteria;
|
||||
|
||||
if ( isMatching || !recursive ) {
|
||||
return isMatching;
|
||||
}
|
||||
|
||||
if ( child.children && child.findOne ) {
|
||||
nestedMatch = child.findOne( criteria, true );
|
||||
}
|
||||
|
||||
return !!nestedMatch;
|
||||
} );
|
||||
|
||||
return nestedMatch || match || null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a class name to the list of classes.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @param {String} className The class name to be added.
|
||||
*/
|
||||
addClass: function( className ) {
|
||||
if ( this.hasClass( className ) )
|
||||
return;
|
||||
|
||||
var c = this.attributes[ 'class' ] || '';
|
||||
|
||||
this.attributes[ 'class' ] = c + ( c ? ' ' : '' ) + className;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a class name from the list of classes.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String} className The class name to be removed.
|
||||
*/
|
||||
removeClass: function( className ) {
|
||||
var classes = this.attributes[ 'class' ];
|
||||
|
||||
if ( !classes )
|
||||
return;
|
||||
|
||||
// We can safely assume that className won't break regexp.
|
||||
// http://stackoverflow.com/questions/448981/what-characters-are-valid-in-css-class-names
|
||||
classes = CKEDITOR.tools.trim( classes.replace( new RegExp( '(?:\\s+|^)' + className + '(?:\\s+|$)' ), ' ' ) );
|
||||
|
||||
if ( classes )
|
||||
this.attributes[ 'class' ] = classes;
|
||||
else
|
||||
delete this.attributes[ 'class' ];
|
||||
},
|
||||
|
||||
/**
|
||||
* Checkes whether this element has a class name.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String} className The class name to be checked.
|
||||
* @returns {Boolean} Whether this element has a `className`.
|
||||
*/
|
||||
hasClass: function( className ) {
|
||||
var classes = this.attributes[ 'class' ];
|
||||
|
||||
if ( !classes )
|
||||
return false;
|
||||
|
||||
return ( new RegExp( '(?:^|\\s)' + className + '(?=\\s|$)' ) ).test( classes );
|
||||
},
|
||||
|
||||
getFilterContext: function( ctx ) {
|
||||
var changes = [];
|
||||
|
||||
if ( !ctx ) {
|
||||
ctx = {
|
||||
nonEditable: false,
|
||||
nestedEditable: false
|
||||
};
|
||||
}
|
||||
|
||||
if ( !ctx.nonEditable && this.attributes.contenteditable == 'false' )
|
||||
changes.push( 'nonEditable', true );
|
||||
// A context to be given nestedEditable must be nonEditable first (by inheritance) (https://dev.ckeditor.com/ticket/11372, https://dev.ckeditor.com/ticket/11698).
|
||||
// Special case: https://dev.ckeditor.com/ticket/11504 - filter starts on <body contenteditable=true>,
|
||||
// so ctx.nonEditable has not been yet set to true.
|
||||
else if ( ctx.nonEditable && !ctx.nestedEditable && this.attributes.contenteditable == 'true' )
|
||||
changes.push( 'nestedEditable', true );
|
||||
|
||||
if ( changes.length ) {
|
||||
ctx = CKEDITOR.tools.copy( ctx );
|
||||
for ( var i = 0; i < changes.length; i += 2 )
|
||||
ctx[ changes[ i ] ] = changes[ i + 1 ];
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
}, true );
|
||||
|
||||
function nameCondition( condition ) {
|
||||
return function( el ) {
|
||||
return el.type == CKEDITOR.NODE_ELEMENT &&
|
||||
( typeof condition == 'string' ? el.name == condition : el.name in condition );
|
||||
};
|
||||
}
|
||||
} )();
|
||||
402
Admin/plugins/ckeditor/core/htmlparser/filter.js
Normal file
402
Admin/plugins/ckeditor/core/htmlparser/filter.js
Normal file
@@ -0,0 +1,402 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Filter is a configurable tool for transforming and filtering {@link CKEDITOR.htmlParser.node nodes}.
|
||||
* It is mainly used during data processing phase which is done not on real DOM nodes,
|
||||
* but on their simplified form represented by {@link CKEDITOR.htmlParser.node} class and its subclasses.
|
||||
*
|
||||
* var filter = new CKEDITOR.htmlParser.filter( {
|
||||
* text: function( value ) {
|
||||
* return '@' + value + '@';
|
||||
* },
|
||||
* elements: {
|
||||
* p: function( element ) {
|
||||
* element.attributes.foo = '1';
|
||||
* }
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p>Foo<b>bar!</b></p>' ),
|
||||
* writer = new CKEDITOR.htmlParser.basicWriter();
|
||||
* filter.applyTo( fragment );
|
||||
* fragment.writeHtml( writer );
|
||||
* writer.getHtml(); // '<p foo="1">@Foo@<b>@bar!@</b></p>'
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
CKEDITOR.htmlParser.filter = CKEDITOR.tools.createClass( {
|
||||
/**
|
||||
* @constructor Creates a filter class instance.
|
||||
* @param {CKEDITOR.htmlParser.filterRulesDefinition} [rules]
|
||||
*/
|
||||
$: function( rules ) {
|
||||
/**
|
||||
* ID of filter instance, which is used to mark elements
|
||||
* to which this filter has been already applied.
|
||||
*
|
||||
* @property {Number} id
|
||||
* @readonly
|
||||
*/
|
||||
this.id = CKEDITOR.tools.getNextNumber();
|
||||
|
||||
/**
|
||||
* Rules for element names.
|
||||
*
|
||||
* @property {CKEDITOR.htmlParser.filterRulesGroup}
|
||||
* @readonly
|
||||
*/
|
||||
this.elementNameRules = new filterRulesGroup();
|
||||
|
||||
/**
|
||||
* Rules for attribute names.
|
||||
*
|
||||
* @property {CKEDITOR.htmlParser.filterRulesGroup}
|
||||
* @readonly
|
||||
*/
|
||||
this.attributeNameRules = new filterRulesGroup();
|
||||
|
||||
/**
|
||||
* Hash of elementName => {@link CKEDITOR.htmlParser.filterRulesGroup rules for elements}.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
this.elementsRules = {};
|
||||
|
||||
/**
|
||||
* Hash of attributeName => {@link CKEDITOR.htmlParser.filterRulesGroup rules for attributes}.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
this.attributesRules = {};
|
||||
|
||||
/**
|
||||
* Rules for text nodes.
|
||||
*
|
||||
* @property {CKEDITOR.htmlParser.filterRulesGroup}
|
||||
* @readonly
|
||||
*/
|
||||
this.textRules = new filterRulesGroup();
|
||||
|
||||
/**
|
||||
* Rules for comment nodes.
|
||||
*
|
||||
* @property {CKEDITOR.htmlParser.filterRulesGroup}
|
||||
* @readonly
|
||||
*/
|
||||
this.commentRules = new filterRulesGroup();
|
||||
|
||||
/**
|
||||
* Rules for a root node.
|
||||
*
|
||||
* @property {CKEDITOR.htmlParser.filterRulesGroup}
|
||||
* @readonly
|
||||
*/
|
||||
this.rootRules = new filterRulesGroup();
|
||||
|
||||
if ( rules )
|
||||
this.addRules( rules, 10 );
|
||||
},
|
||||
|
||||
proto: {
|
||||
/**
|
||||
* Add rules to this filter.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.filterRulesDefinition} rules Object containing filter rules.
|
||||
* @param {Object/Number} [options] Object containing rules' options or a priority
|
||||
* (for a backward compatibility with CKEditor versions up to 4.2.x).
|
||||
* @param {Number} [options.priority=10] The priority of a rule.
|
||||
* @param {Boolean} [options.applyToAll=false] Whether to apply rule to non-editable
|
||||
* elements and their descendants too.
|
||||
*/
|
||||
addRules: function( rules, options ) {
|
||||
var priority;
|
||||
|
||||
// Backward compatibility.
|
||||
if ( typeof options == 'number' )
|
||||
priority = options;
|
||||
// New version - try reading from options.
|
||||
else if ( options && ( 'priority' in options ) )
|
||||
priority = options.priority;
|
||||
|
||||
// Defaults.
|
||||
if ( typeof priority != 'number' )
|
||||
priority = 10;
|
||||
if ( typeof options != 'object' )
|
||||
options = {};
|
||||
|
||||
// Add the elementNames.
|
||||
if ( rules.elementNames )
|
||||
this.elementNameRules.addMany( rules.elementNames, priority, options );
|
||||
|
||||
// Add the attributeNames.
|
||||
if ( rules.attributeNames )
|
||||
this.attributeNameRules.addMany( rules.attributeNames, priority, options );
|
||||
|
||||
// Add the elements.
|
||||
if ( rules.elements )
|
||||
addNamedRules( this.elementsRules, rules.elements, priority, options );
|
||||
|
||||
// Add the attributes.
|
||||
if ( rules.attributes )
|
||||
addNamedRules( this.attributesRules, rules.attributes, priority, options );
|
||||
|
||||
// Add the text.
|
||||
if ( rules.text )
|
||||
this.textRules.add( rules.text, priority, options );
|
||||
|
||||
// Add the comment.
|
||||
if ( rules.comment )
|
||||
this.commentRules.add( rules.comment, priority, options );
|
||||
|
||||
// Add root node rules.
|
||||
if ( rules.root )
|
||||
this.rootRules.add( rules.root, priority, options );
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply this filter to given node.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.node} node The node to be filtered.
|
||||
*/
|
||||
applyTo: function( node ) {
|
||||
node.filter( this );
|
||||
},
|
||||
|
||||
onElementName: function( context, name ) {
|
||||
return this.elementNameRules.execOnName( context, name );
|
||||
},
|
||||
|
||||
onAttributeName: function( context, name ) {
|
||||
return this.attributeNameRules.execOnName( context, name );
|
||||
},
|
||||
|
||||
onText: function( context, text, node ) {
|
||||
return this.textRules.exec( context, text, node );
|
||||
},
|
||||
|
||||
onComment: function( context, commentText, comment ) {
|
||||
return this.commentRules.exec( context, commentText, comment );
|
||||
},
|
||||
|
||||
onRoot: function( context, element ) {
|
||||
return this.rootRules.exec( context, element );
|
||||
},
|
||||
|
||||
onElement: function( context, element ) {
|
||||
// We must apply filters set to the specific element name as
|
||||
// well as those set to the generic ^/$ name. So, add both to an
|
||||
// array and process them in a small loop.
|
||||
var rulesGroups = [ this.elementsRules[ '^' ], this.elementsRules[ element.name ], this.elementsRules.$ ],
|
||||
rulesGroup, ret;
|
||||
|
||||
for ( var i = 0; i < 3; i++ ) {
|
||||
rulesGroup = rulesGroups[ i ];
|
||||
if ( rulesGroup ) {
|
||||
ret = rulesGroup.exec( context, element, this );
|
||||
|
||||
if ( ret === false )
|
||||
return null;
|
||||
|
||||
if ( ret && ret != element )
|
||||
return this.onNode( context, ret );
|
||||
|
||||
// The non-root element has been dismissed by one of the filters.
|
||||
if ( element.parent && !element.name )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
},
|
||||
|
||||
onNode: function( context, node ) {
|
||||
var type = node.type;
|
||||
|
||||
return type == CKEDITOR.NODE_ELEMENT ? this.onElement( context, node ) :
|
||||
type == CKEDITOR.NODE_TEXT ? new CKEDITOR.htmlParser.text( this.onText( context, node.value, node ) ) :
|
||||
type == CKEDITOR.NODE_COMMENT ? new CKEDITOR.htmlParser.comment( this.onComment( context, node.value, node ) ) : null;
|
||||
},
|
||||
|
||||
onAttribute: function( context, element, name, value ) {
|
||||
var rulesGroup = this.attributesRules[ name ];
|
||||
|
||||
if ( rulesGroup )
|
||||
return rulesGroup.exec( context, value, element, this );
|
||||
return value;
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* Class grouping filter rules for one subject (like element or attribute names).
|
||||
*
|
||||
* @class CKEDITOR.htmlParser.filterRulesGroup
|
||||
*/
|
||||
function filterRulesGroup() {
|
||||
/**
|
||||
* Array of objects containing rule, priority and options.
|
||||
*
|
||||
* @property {Object[]}
|
||||
* @readonly
|
||||
*/
|
||||
this.rules = [];
|
||||
}
|
||||
|
||||
CKEDITOR.htmlParser.filterRulesGroup = filterRulesGroup;
|
||||
|
||||
filterRulesGroup.prototype = {
|
||||
/**
|
||||
* Adds specified rule to this group.
|
||||
*
|
||||
* @param {Function/Array} rule Function for function based rule or [ pattern, replacement ] array for
|
||||
* rule applicable to names.
|
||||
* @param {Number} priority
|
||||
* @param options
|
||||
*/
|
||||
add: function( rule, priority, options ) {
|
||||
this.rules.splice( this.findIndex( priority ), 0, {
|
||||
value: rule,
|
||||
priority: priority,
|
||||
options: options
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds specified rules to this group.
|
||||
*
|
||||
* @param {Array} rules Array of rules - see {@link #add}.
|
||||
* @param {Number} priority
|
||||
* @param options
|
||||
*/
|
||||
addMany: function( rules, priority, options ) {
|
||||
var args = [ this.findIndex( priority ), 0 ];
|
||||
|
||||
for ( var i = 0, len = rules.length; i < len; i++ ) {
|
||||
args.push( {
|
||||
value: rules[ i ],
|
||||
priority: priority,
|
||||
options: options
|
||||
} );
|
||||
}
|
||||
|
||||
this.rules.splice.apply( this.rules, args );
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds an index at which rule with given priority should be inserted.
|
||||
*
|
||||
* @param {Number} priority
|
||||
* @returns {Number} Index.
|
||||
*/
|
||||
findIndex: function( priority ) {
|
||||
var rules = this.rules,
|
||||
len = rules.length,
|
||||
i = len - 1;
|
||||
|
||||
// Search from the end, because usually rules will be added with default priority, so
|
||||
// we will be able to stop loop quickly.
|
||||
while ( i >= 0 && priority < rules[ i ].priority )
|
||||
i--;
|
||||
|
||||
return i + 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes this rules group on given value. Applicable only if function based rules were added.
|
||||
*
|
||||
* All arguments passed to this function will be forwarded to rules' functions.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.node/CKEDITOR.htmlParser.fragment/String} currentValue The value to be filtered.
|
||||
* @returns {CKEDITOR.htmlParser.node/CKEDITOR.htmlParser.fragment/String} Filtered value.
|
||||
*/
|
||||
exec: function( context, currentValue ) {
|
||||
var isNode = currentValue instanceof CKEDITOR.htmlParser.node || currentValue instanceof CKEDITOR.htmlParser.fragment,
|
||||
// Splice '1' to remove context, which we don't want to pass to filter rules.
|
||||
args = Array.prototype.slice.call( arguments, 1 ),
|
||||
rules = this.rules,
|
||||
len = rules.length,
|
||||
orgType, orgName, ret, i, rule;
|
||||
|
||||
for ( i = 0; i < len; i++ ) {
|
||||
// Backup the node info before filtering.
|
||||
if ( isNode ) {
|
||||
orgType = currentValue.type;
|
||||
orgName = currentValue.name;
|
||||
}
|
||||
|
||||
rule = rules[ i ];
|
||||
if ( isRuleApplicable( context, rule ) ) {
|
||||
ret = rule.value.apply( null, args );
|
||||
|
||||
if ( ret === false )
|
||||
return ret;
|
||||
|
||||
// We're filtering node (element/fragment).
|
||||
// No further filtering if it's not anymore fitable for the subsequent filters.
|
||||
if ( isNode && ret && ( ret.name != orgName || ret.type != orgType ) )
|
||||
return ret;
|
||||
|
||||
// Update currentValue and corresponding argument in args array.
|
||||
// Updated values will be used in next for-loop step.
|
||||
if ( ret != null )
|
||||
args[ 0 ] = currentValue = ret;
|
||||
|
||||
// ret == undefined will continue loop as nothing has happened.
|
||||
}
|
||||
}
|
||||
|
||||
return currentValue;
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes this rules group on name. Applicable only if filter rules for names were added.
|
||||
*
|
||||
* @param {String} currentName The name to be filtered.
|
||||
* @returns {String} Filtered name.
|
||||
*/
|
||||
execOnName: function( context, currentName ) {
|
||||
var i = 0,
|
||||
rules = this.rules,
|
||||
len = rules.length,
|
||||
rule;
|
||||
|
||||
for ( ; currentName && i < len; i++ ) {
|
||||
rule = rules[ i ];
|
||||
if ( isRuleApplicable( context, rule ) )
|
||||
currentName = currentName.replace( rule.value[ 0 ], rule.value[ 1 ] );
|
||||
}
|
||||
|
||||
return currentName;
|
||||
}
|
||||
};
|
||||
|
||||
function addNamedRules( rulesGroups, newRules, priority, options ) {
|
||||
var ruleName, rulesGroup;
|
||||
|
||||
for ( ruleName in newRules ) {
|
||||
rulesGroup = rulesGroups[ ruleName ];
|
||||
|
||||
if ( !rulesGroup )
|
||||
rulesGroup = rulesGroups[ ruleName ] = new filterRulesGroup();
|
||||
|
||||
rulesGroup.add( newRules[ ruleName ], priority, options );
|
||||
}
|
||||
}
|
||||
|
||||
function isRuleApplicable( context, rule ) {
|
||||
if ( context.nonEditable && !rule.options.applyToAll )
|
||||
return false;
|
||||
|
||||
if ( context.nestedEditable && rule.options.excludeNestedEditable )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} )();
|
||||
156
Admin/plugins/ckeditor/core/htmlparser/filterRulesDefinition.js
Normal file
156
Admin/plugins/ckeditor/core/htmlparser/filterRulesDefinition.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.htmlParser.filterRulesDefinition} class
|
||||
* that contains the definition of filter rules. This file is for
|
||||
* documentation purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract class describing the definition of {@link CKEDITOR.htmlParser.filter} rules.
|
||||
*
|
||||
* Definition object represents rules as a set of properties with callback functions
|
||||
* to be applied for transforming and filtering content upon data processing.
|
||||
*
|
||||
* It can be used with {@link CKEDITOR.htmlParser.filter} and {@link CKEDITOR.htmlParser.filter#addRules}.
|
||||
*
|
||||
* @class CKEDITOR.htmlParser.filterRulesDefinition
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {CKEDITOR.htmlParser.nameTransformRule[]} elementNames An array of rules for element names transformation.
|
||||
* Every rule match will be replaced by the given string.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* elementNames: [
|
||||
* [ /^div$/, 'p' ], // Converts 'div' into 'p'.
|
||||
* [ /^cke:?/, '' ] // Removes 'cke:' prefixes.
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {CKEDITOR.htmlParser.nameTransformRule[]} attributeNames An array of rules for attribute names transformation.
|
||||
* Every matching string from the first item will be converted into the second.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* attributeNames: [
|
||||
* [ 'data-foo', 'data-bar' ],
|
||||
* // Converts the string in the attribute name from 'data-foo' into 'data-bar'.
|
||||
* // Note that the 'data-foo-baz' attribute will be converted into 'data-bar-baz'.
|
||||
*
|
||||
* [ /^data-custom$/, 'data-cke' ]
|
||||
* // Converts the 'data-custom' attribute into 'data-cke'.
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {Object.<String, Function>} elements An object containing pairs of element selectors
|
||||
* and functions used upon element filtering and transformation.
|
||||
*
|
||||
* A selector can be either an element name or one of the following: `^`, `$`.
|
||||
*
|
||||
* `^` and `$` are to be applied on every filtered element. The first is applied before the element-specific filter,
|
||||
* and the second is applied after the element-specific filter.
|
||||
*
|
||||
* The function can contain a return statement:
|
||||
*
|
||||
* * If `false` is returned, the element is removed.
|
||||
* * If another element is returned, it overwrites the original element.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* elements: {
|
||||
* '^': function( element ) {
|
||||
* // Element transformation to be applied on every filtered element.
|
||||
* // This will be applied as the first filter.
|
||||
* },
|
||||
* div: function( element ) {
|
||||
* // Element transformation.
|
||||
* },
|
||||
* p: function() {
|
||||
* return false; // Removes each '<p>' element.
|
||||
* },
|
||||
* '$': function( element ) {
|
||||
* // Element transformation to be applied on every filtered element.
|
||||
* // This will be applied after other defined filters.
|
||||
* },
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {Object.<String, Function>} attributes An object containing pairs of element attribute names
|
||||
* and functions used upon attribute filtering and transformation.
|
||||
*
|
||||
* Returning `false` removes the attribute.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* attributes: {
|
||||
* 'class': function( value, element ) {
|
||||
* if ( element.name === 'div' ) {
|
||||
* return value + ' cke_div' // Adds the 'cke_div' class to every filtered div element.
|
||||
* }
|
||||
* },
|
||||
* id: function() {
|
||||
* return false; // Removes the 'id' attribute from every filtered element.
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {Function} text Function for text content transforming. Returned value replaces text.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* text: function( value, element ) {
|
||||
* return value.toLowerCase(); // Transforms each text into lower case.
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {Function} comment Function for comments filtering and transforming. Returned value replaces comment text.
|
||||
* If `false` is returned, the comment is removed.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* comment: function( value, element ) {
|
||||
* return false; // Removes the comment.
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {Function} root Function for root element transforming.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* root: function( element ) {
|
||||
* element.children.push( someElement ); // Appends a child to the root element.
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
743
Admin/plugins/ckeditor/core/htmlparser/fragment.js
Normal file
743
Admin/plugins/ckeditor/core/htmlparser/fragment.js
Normal file
@@ -0,0 +1,743 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A lightweight representation of an HTML DOM structure.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a fragment class instance.
|
||||
*/
|
||||
CKEDITOR.htmlParser.fragment = function() {
|
||||
/**
|
||||
* The nodes contained in the root of this fragment.
|
||||
*
|
||||
* var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<b>Sample</b> Text' );
|
||||
* alert( fragment.children.length ); // 2
|
||||
*/
|
||||
this.children = [];
|
||||
|
||||
/**
|
||||
* Get the fragment parent. Should always be null.
|
||||
*
|
||||
* @property {Object} [=null]
|
||||
*/
|
||||
this.parent = null;
|
||||
|
||||
/** @private */
|
||||
this._ = {
|
||||
isBlockLike: true,
|
||||
hasInlineStarted: false
|
||||
};
|
||||
};
|
||||
|
||||
( function() {
|
||||
// Block-level elements whose internal structure should be respected during
|
||||
// parser fixing.
|
||||
var nonBreakingBlocks = CKEDITOR.tools.extend( { table: 1, ul: 1, ol: 1, dl: 1 }, CKEDITOR.dtd.table, CKEDITOR.dtd.ul, CKEDITOR.dtd.ol, CKEDITOR.dtd.dl );
|
||||
|
||||
var listBlocks = { ol: 1, ul: 1 };
|
||||
|
||||
// Dtd of the fragment element, basically it accept anything except for intermediate structure, e.g. orphan <li>.
|
||||
var rootDtd = CKEDITOR.tools.extend( {}, { html: 1 }, CKEDITOR.dtd.html, CKEDITOR.dtd.body, CKEDITOR.dtd.head, { style: 1, script: 1 } );
|
||||
|
||||
// Which element to create when encountered not allowed content.
|
||||
var structureFixes = {
|
||||
ul: 'li',
|
||||
ol: 'li',
|
||||
dl: 'dd',
|
||||
table: 'tbody',
|
||||
tbody: 'tr',
|
||||
thead: 'tr',
|
||||
tfoot: 'tr',
|
||||
tr: 'td'
|
||||
};
|
||||
|
||||
function isRemoveEmpty( node ) {
|
||||
// Keep marked element event if it is empty.
|
||||
if ( node.attributes[ 'data-cke-survive' ] )
|
||||
return false;
|
||||
|
||||
// Empty link is to be removed when empty but not anchor. (https://dev.ckeditor.com/ticket/7894)
|
||||
return node.name == 'a' && node.attributes.href || CKEDITOR.dtd.$removeEmpty[ node.name ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link CKEDITOR.htmlParser.fragment} from an HTML string.
|
||||
*
|
||||
* var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<b>Sample</b> Text' );
|
||||
* alert( fragment.children[ 0 ].name ); // 'b'
|
||||
* alert( fragment.children[ 1 ].value ); // ' Text'
|
||||
*
|
||||
* @static
|
||||
* @param {String} fragmentHtml The HTML to be parsed, filling the fragment.
|
||||
* @param {CKEDITOR.htmlParser.element/String} [parent] Optional contextual
|
||||
* element which makes the content been parsed as the content of this element and fix
|
||||
* to match it.
|
||||
* If not provided, then {@link CKEDITOR.htmlParser.fragment} will be used
|
||||
* as the parent and it will be returned.
|
||||
* @param {String/Boolean} [fixingBlock] When `parent` is a block limit element,
|
||||
* and the param is a string value other than `false`, it is to
|
||||
* avoid having block-less content as the direct children of parent by wrapping
|
||||
* the content with a block element of the specified tag, e.g.
|
||||
* when `fixingBlock` specified as `p`, the content `<body><i>foo</i></body>`
|
||||
* will be fixed into `<body><p><i>foo</i></p></body>`.
|
||||
* @returns {CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} The created fragment or passed `parent`.
|
||||
*/
|
||||
CKEDITOR.htmlParser.fragment.fromHtml = function( fragmentHtml, parent, fixingBlock ) {
|
||||
var parser = new CKEDITOR.htmlParser();
|
||||
|
||||
var root = parent instanceof CKEDITOR.htmlParser.element ? parent : typeof parent == 'string' ? new CKEDITOR.htmlParser.element( parent ) : new CKEDITOR.htmlParser.fragment();
|
||||
|
||||
var pendingInline = [],
|
||||
pendingBRs = [],
|
||||
currentNode = root,
|
||||
// Indicate we're inside a <textarea> element, spaces should be touched differently.
|
||||
inTextarea = root.name == 'textarea',
|
||||
// Indicate we're inside a <pre> element, spaces should be touched differently.
|
||||
inPre = root.name == 'pre';
|
||||
|
||||
function checkPending( newTagName ) {
|
||||
var pendingBRsSent;
|
||||
|
||||
if ( pendingInline.length > 0 ) {
|
||||
for ( var i = 0; i < pendingInline.length; i++ ) {
|
||||
var pendingElement = pendingInline[ i ],
|
||||
pendingName = pendingElement.name,
|
||||
pendingDtd = CKEDITOR.dtd[ pendingName ],
|
||||
currentDtd = currentNode.name && CKEDITOR.dtd[ currentNode.name ];
|
||||
|
||||
if ( ( !currentDtd || currentDtd[ pendingName ] ) && ( !newTagName || !pendingDtd || pendingDtd[ newTagName ] || !CKEDITOR.dtd[ newTagName ] ) ) {
|
||||
if ( !pendingBRsSent ) {
|
||||
sendPendingBRs();
|
||||
pendingBRsSent = 1;
|
||||
}
|
||||
|
||||
// Get a clone for the pending element.
|
||||
pendingElement = pendingElement.clone();
|
||||
|
||||
// Add it to the current node and make it the current,
|
||||
// so the new element will be added inside of it.
|
||||
pendingElement.parent = currentNode;
|
||||
currentNode = pendingElement;
|
||||
|
||||
// Remove the pending element (back the index by one
|
||||
// to properly process the next entry).
|
||||
pendingInline.splice( i, 1 );
|
||||
i--;
|
||||
} else {
|
||||
// Some element of the same type cannot be nested, flat them,
|
||||
// e.g. <a href="#">foo<a href="#">bar</a></a>. (https://dev.ckeditor.com/ticket/7894)
|
||||
if ( pendingName == currentNode.name )
|
||||
addElement( currentNode, currentNode.parent, 1 ), i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sendPendingBRs() {
|
||||
while ( pendingBRs.length )
|
||||
addElement( pendingBRs.shift(), currentNode );
|
||||
}
|
||||
|
||||
function shiftBRsPosition() {
|
||||
var shiftLineBreaks = CKEDITOR.config.shiftLineBreaks;
|
||||
|
||||
if ( shiftLineBreaks === true || !pendingBRs.length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( typeof shiftLineBreaks !== 'function' ) {
|
||||
sendPendingBRs();
|
||||
return;
|
||||
}
|
||||
|
||||
var result = shiftLineBreaks( pendingBRs[ pendingBRs.length - 1 ] );
|
||||
|
||||
if ( result === true ) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendPendingBRs();
|
||||
|
||||
if ( result instanceof CKEDITOR.htmlParser.text ) {
|
||||
currentNode.add( result );
|
||||
}
|
||||
|
||||
if ( result instanceof CKEDITOR.htmlParser.element ) {
|
||||
addElement( result, currentNode );
|
||||
}
|
||||
}
|
||||
|
||||
// Rtrim empty spaces on block end boundary. (https://dev.ckeditor.com/ticket/3585)
|
||||
function removeTailWhitespace( element ) {
|
||||
if ( element._.isBlockLike && element.name != 'pre' && element.name != 'textarea' ) {
|
||||
|
||||
var length = element.children.length,
|
||||
lastChild = element.children[ length - 1 ],
|
||||
text;
|
||||
if ( lastChild && lastChild.type == CKEDITOR.NODE_TEXT ) {
|
||||
if ( !( text = CKEDITOR.tools.rtrim( lastChild.value ) ) )
|
||||
element.children.length = length - 1;
|
||||
else
|
||||
lastChild.value = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Beside of simply append specified element to target, this function also takes
|
||||
// care of other dirty lifts like forcing block in body, trimming spaces at
|
||||
// the block boundaries etc.
|
||||
//
|
||||
// @param {Element} element The element to be added as the last child of {@link target}.
|
||||
// @param {Element} target The parent element to relieve the new node.
|
||||
// @param {Boolean} [moveCurrent=false] Don't change the "currentNode" global unless
|
||||
// there's a return point node specified on the element, otherwise move current onto {@link target} node.
|
||||
//
|
||||
function addElement( element, target, moveCurrent ) {
|
||||
target = target || currentNode || root;
|
||||
|
||||
// Current element might be mangled by fix body below,
|
||||
// save it for restore later.
|
||||
var savedCurrent = currentNode;
|
||||
|
||||
// Ignore any element that has already been added.
|
||||
if ( element.previous === undefined ) {
|
||||
if ( checkAutoParagraphing( target, element ) ) {
|
||||
// Create a <p> in the fragment.
|
||||
currentNode = target;
|
||||
parser.onTagOpen( fixingBlock, {} );
|
||||
|
||||
// The new target now is the <p>.
|
||||
element.returnPoint = target = currentNode;
|
||||
}
|
||||
|
||||
removeTailWhitespace( element );
|
||||
|
||||
// Avoid adding empty inline.
|
||||
if ( !( isRemoveEmpty( element ) && !element.children.length ) )
|
||||
target.add( element );
|
||||
|
||||
if ( element.name == 'pre' )
|
||||
inPre = false;
|
||||
|
||||
if ( element.name == 'textarea' )
|
||||
inTextarea = false;
|
||||
}
|
||||
|
||||
if ( element.returnPoint ) {
|
||||
currentNode = element.returnPoint;
|
||||
delete element.returnPoint;
|
||||
} else {
|
||||
currentNode = moveCurrent ? target : savedCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
// Auto paragraphing should happen when inline content enters the root element.
|
||||
function checkAutoParagraphing( parent, node ) {
|
||||
|
||||
// Check for parent that can contain block.
|
||||
if ( ( parent == root || parent.name == 'body' ) && fixingBlock &&
|
||||
( !parent.name || CKEDITOR.dtd[ parent.name ][ fixingBlock ] ) ) {
|
||||
var name, realName;
|
||||
|
||||
if ( node.attributes && ( realName = node.attributes[ 'data-cke-real-element-type' ] ) )
|
||||
name = realName;
|
||||
else
|
||||
name = node.name;
|
||||
|
||||
// Text node, inline elements are subjected, except for <script>/<style>.
|
||||
return name && name in CKEDITOR.dtd.$inline &&
|
||||
!( name in CKEDITOR.dtd.head ) &&
|
||||
!node.isOrphan ||
|
||||
node.type == CKEDITOR.NODE_TEXT;
|
||||
}
|
||||
}
|
||||
|
||||
// Judge whether two element tag names are likely the siblings from the same
|
||||
// structural element.
|
||||
function possiblySibling( tag1, tag2 ) {
|
||||
|
||||
if ( tag1 in CKEDITOR.dtd.$listItem || tag1 in CKEDITOR.dtd.$tableContent )
|
||||
return tag1 == tag2 || tag1 == 'dt' && tag2 == 'dd' || tag1 == 'dd' && tag2 == 'dt';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parser.onTagOpen = function( tagName, attributes, selfClosing, optionalClose ) {
|
||||
var element = new CKEDITOR.htmlParser.element( tagName, attributes );
|
||||
|
||||
// "isEmpty" will be always "false" for unknown elements, so we
|
||||
// must force it if the parser has identified it as a selfClosing tag.
|
||||
if ( element.isUnknown && selfClosing )
|
||||
element.isEmpty = true;
|
||||
|
||||
// Check for optional closed elements, including browser quirks and manually opened blocks.
|
||||
element.isOptionalClose = optionalClose;
|
||||
|
||||
// This is a tag to be removed if empty, so do not add it immediately.
|
||||
if ( isRemoveEmpty( element ) ) {
|
||||
pendingInline.push( element );
|
||||
return;
|
||||
} else if ( tagName == 'pre' )
|
||||
inPre = true;
|
||||
else if ( tagName == 'br' && inPre ) {
|
||||
currentNode.add( new CKEDITOR.htmlParser.text( '\n' ) );
|
||||
return;
|
||||
} else if ( tagName == 'textarea' ) {
|
||||
inTextarea = true;
|
||||
}
|
||||
|
||||
if ( tagName == 'br' ) {
|
||||
pendingBRs.push( element );
|
||||
return;
|
||||
}
|
||||
|
||||
while ( 1 ) {
|
||||
var currentName = currentNode.name;
|
||||
|
||||
var currentDtd = currentName ? ( CKEDITOR.dtd[ currentName ] || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ) : rootDtd;
|
||||
|
||||
// If the element cannot be child of the current element.
|
||||
if ( !element.isUnknown && !currentNode.isUnknown && !currentDtd[ tagName ] ) {
|
||||
// Current node doesn't have a close tag, time for a close
|
||||
// as this element isn't fit in. (https://dev.ckeditor.com/ticket/7497)
|
||||
if ( currentNode.isOptionalClose )
|
||||
parser.onTagClose( currentName );
|
||||
// Fixing malformed nested lists by moving it into a previous list item. (https://dev.ckeditor.com/ticket/3828)
|
||||
else if ( tagName in listBlocks && currentName in listBlocks ) {
|
||||
var children = currentNode.children,
|
||||
lastChild = children[ children.length - 1 ];
|
||||
|
||||
// Establish the list item if it's not existed.
|
||||
if ( !( lastChild && lastChild.name == 'li' ) )
|
||||
addElement( ( lastChild = new CKEDITOR.htmlParser.element( 'li' ) ), currentNode );
|
||||
|
||||
!element.returnPoint && ( element.returnPoint = currentNode );
|
||||
currentNode = lastChild;
|
||||
}
|
||||
// Establish new list root for orphan list items, but NOT to create
|
||||
// new list for the following ones, fix them instead. (https://dev.ckeditor.com/ticket/6975)
|
||||
// <dl><dt>foo<dd>bar</dl>
|
||||
// <ul><li>foo<li>bar</ul>
|
||||
else if ( tagName in CKEDITOR.dtd.$listItem &&
|
||||
!possiblySibling( tagName, currentName ) ) {
|
||||
parser.onTagOpen( tagName == 'li' ? 'ul' : 'dl', {}, 0, 1 );
|
||||
}
|
||||
// We're inside a structural block like table and list, AND the incoming element
|
||||
// is not of the same type (e.g. <td>td1<td>td2</td>), we simply add this new one before it,
|
||||
// and most importantly, return back to here once this element is added,
|
||||
// e.g. <table><tr><td>td1</td><p>p1</p><td>td2</td></tr></table>
|
||||
else if ( currentName in nonBreakingBlocks &&
|
||||
!possiblySibling( tagName, currentName ) ) {
|
||||
!element.returnPoint && ( element.returnPoint = currentNode );
|
||||
currentNode = currentNode.parent;
|
||||
} else {
|
||||
// The current element is an inline element, which
|
||||
// need to be continued even after the close, so put
|
||||
// it in the pending list.
|
||||
if ( currentName in CKEDITOR.dtd.$inline )
|
||||
pendingInline.unshift( currentNode );
|
||||
|
||||
// The most common case where we just need to close the
|
||||
// current one and append the new one to the parent.
|
||||
if ( currentNode.parent )
|
||||
addElement( currentNode, currentNode.parent, 1 );
|
||||
// We've tried our best to fix the embarrassment here, while
|
||||
// this element still doesn't find it's parent, mark it as
|
||||
// orphan and show our tolerance to it.
|
||||
else {
|
||||
element.isOrphan = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
checkPending( tagName );
|
||||
sendPendingBRs();
|
||||
|
||||
element.parent = currentNode;
|
||||
|
||||
if ( element.isEmpty )
|
||||
addElement( element );
|
||||
else
|
||||
currentNode = element;
|
||||
};
|
||||
|
||||
parser.onTagClose = function( tagName ) {
|
||||
// Check if there is any pending tag to be closed.
|
||||
for ( var i = pendingInline.length - 1; i >= 0; i-- ) {
|
||||
// If found, just remove it from the list.
|
||||
if ( tagName == pendingInline[ i ].name ) {
|
||||
pendingInline.splice( i, 1 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var pendingAdd = [],
|
||||
newPendingInline = [],
|
||||
candidate = currentNode;
|
||||
|
||||
while ( candidate != root && candidate.name != tagName ) {
|
||||
// If this is an inline element, add it to the pending list, if we're
|
||||
// really closing one of the parents element later, they will continue
|
||||
// after it.
|
||||
if ( !candidate._.isBlockLike )
|
||||
newPendingInline.unshift( candidate );
|
||||
|
||||
// This node should be added to it's parent at this point. But,
|
||||
// it should happen only if the closing tag is really closing
|
||||
// one of the nodes. So, for now, we just cache it.
|
||||
pendingAdd.push( candidate );
|
||||
|
||||
// Make sure return point is properly restored.
|
||||
candidate = candidate.returnPoint || candidate.parent;
|
||||
}
|
||||
|
||||
if ( candidate != root ) {
|
||||
// Add all elements that have been found in the above loop.
|
||||
for ( i = 0; i < pendingAdd.length; i++ ) {
|
||||
var node = pendingAdd[ i ];
|
||||
addElement( node, node.parent );
|
||||
}
|
||||
|
||||
currentNode = candidate;
|
||||
|
||||
if ( candidate._.isBlockLike ) {
|
||||
sendPendingBRs();
|
||||
} else {
|
||||
shiftBRsPosition();
|
||||
}
|
||||
|
||||
addElement( candidate, candidate.parent );
|
||||
|
||||
// The parent should start receiving new nodes now, except if
|
||||
// addElement changed the currentNode.
|
||||
if ( candidate == currentNode )
|
||||
currentNode = currentNode.parent;
|
||||
|
||||
pendingInline = pendingInline.concat( newPendingInline );
|
||||
}
|
||||
|
||||
if ( tagName == 'body' )
|
||||
fixingBlock = false;
|
||||
};
|
||||
|
||||
parser.onText = function( text ) {
|
||||
// Trim empty spaces at beginning of text contents except <pre> and <textarea>.
|
||||
if ( ( !currentNode._.hasInlineStarted || pendingBRs.length ) && !inPre && !inTextarea ) {
|
||||
text = CKEDITOR.tools.ltrim( text );
|
||||
|
||||
if ( text.length === 0 )
|
||||
return;
|
||||
}
|
||||
|
||||
var currentName = currentNode.name,
|
||||
currentDtd = currentName ? ( CKEDITOR.dtd[ currentName ] || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ) : rootDtd;
|
||||
|
||||
// Fix orphan text in list/table. (https://dev.ckeditor.com/ticket/8540) (https://dev.ckeditor.com/ticket/8870)
|
||||
if ( !inTextarea && !currentDtd[ '#' ] && currentName in nonBreakingBlocks ) {
|
||||
parser.onTagOpen( structureFixes[ currentName ] || '' );
|
||||
parser.onText( text );
|
||||
return;
|
||||
}
|
||||
|
||||
sendPendingBRs();
|
||||
checkPending();
|
||||
|
||||
// Shrinking consequential spaces into one single for all elements
|
||||
// text contents.
|
||||
if ( !inPre && !inTextarea )
|
||||
text = text.replace( /[\t\r\n ]{2,}|[\t\r\n]/g, ' ' );
|
||||
|
||||
text = new CKEDITOR.htmlParser.text( text );
|
||||
|
||||
|
||||
if ( checkAutoParagraphing( currentNode, text ) )
|
||||
this.onTagOpen( fixingBlock, {}, 0, 1 );
|
||||
|
||||
currentNode.add( text );
|
||||
};
|
||||
|
||||
parser.onCDATA = function( cdata ) {
|
||||
currentNode.add( new CKEDITOR.htmlParser.cdata( cdata ) );
|
||||
};
|
||||
|
||||
parser.onComment = function( comment ) {
|
||||
sendPendingBRs();
|
||||
checkPending();
|
||||
currentNode.add( new CKEDITOR.htmlParser.comment( comment ) );
|
||||
};
|
||||
|
||||
// Parse it.
|
||||
parser.parse( fragmentHtml );
|
||||
|
||||
sendPendingBRs();
|
||||
|
||||
// Close all pending nodes, make sure return point is properly restored.
|
||||
while ( currentNode != root )
|
||||
addElement( currentNode, currentNode.parent, 1 );
|
||||
|
||||
removeTailWhitespace( root );
|
||||
|
||||
return root;
|
||||
};
|
||||
|
||||
CKEDITOR.htmlParser.fragment.prototype = {
|
||||
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_DOCUMENT_FRAGMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_DOCUMENT_FRAGMENT,
|
||||
|
||||
/**
|
||||
* Adds a node to this fragment.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.node} node The node to be added.
|
||||
* @param {Number} [index] From where the insertion happens.
|
||||
*/
|
||||
add: function( node, index ) {
|
||||
isNaN( index ) && ( index = this.children.length );
|
||||
|
||||
var previous = index > 0 ? this.children[ index - 1 ] : null;
|
||||
if ( previous ) {
|
||||
// If the block to be appended is following text, trim spaces at
|
||||
// the right of it.
|
||||
if ( node._.isBlockLike && previous.type == CKEDITOR.NODE_TEXT ) {
|
||||
previous.value = CKEDITOR.tools.rtrim( previous.value );
|
||||
|
||||
// If we have completely cleared the previous node.
|
||||
if ( previous.value.length === 0 ) {
|
||||
// Remove it from the list and add the node again.
|
||||
this.children.pop();
|
||||
this.add( node );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
previous.next = node;
|
||||
}
|
||||
|
||||
node.previous = previous;
|
||||
node.parent = this;
|
||||
|
||||
this.children.splice( index, 0, node );
|
||||
|
||||
if ( !this._.hasInlineStarted )
|
||||
this._.hasInlineStarted = node.type == CKEDITOR.NODE_TEXT || ( node.type == CKEDITOR.NODE_ELEMENT && !node._.isBlockLike );
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter this fragment's content with given filter.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
*/
|
||||
filter: function( filter, context ) {
|
||||
context = this.getFilterContext( context );
|
||||
|
||||
// Apply the root filter.
|
||||
filter.onRoot( context, this );
|
||||
|
||||
this.filterChildren( filter, false, context );
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter this fragment's children with given filter.
|
||||
*
|
||||
* Element's children may only be filtered once by one
|
||||
* instance of filter.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
* @param {Boolean} [filterRoot] Whether to apply the "root" filter rule specified in the `filter`.
|
||||
*/
|
||||
filterChildren: function( filter, filterRoot, context ) {
|
||||
// If this element's children were already filtered
|
||||
// by current filter, don't filter them 2nd time.
|
||||
// This situation may occur when filtering bottom-up
|
||||
// (filterChildren() called manually in element's filter),
|
||||
// or in unpredictable edge cases when filter
|
||||
// is manipulating DOM structure.
|
||||
if ( this.childrenFilteredBy == filter.id )
|
||||
return;
|
||||
|
||||
context = this.getFilterContext( context );
|
||||
|
||||
// Filtering root if enforced.
|
||||
if ( filterRoot && !this.parent )
|
||||
filter.onRoot( context, this );
|
||||
|
||||
this.childrenFilteredBy = filter.id;
|
||||
|
||||
// Don't cache anything, children array may be modified by filter rule.
|
||||
for ( var i = 0; i < this.children.length; i++ ) {
|
||||
// Stay in place if filter returned false, what means
|
||||
// that node has been removed.
|
||||
if ( this.children[ i ].filter( filter, context ) === false )
|
||||
i--;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the fragment HTML to a {@link CKEDITOR.htmlParser.basicWriter}.
|
||||
*
|
||||
* var writer = new CKEDITOR.htmlWriter();
|
||||
* var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<P><B>Example' );
|
||||
* fragment.writeHtml( writer );
|
||||
* alert( writer.getHtml() ); // '<p><b>Example</b></p>'
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter] The filter to use when writing the HTML.
|
||||
*/
|
||||
writeHtml: function( writer, filter ) {
|
||||
if ( filter )
|
||||
this.filter( filter );
|
||||
|
||||
this.writeChildrenHtml( writer );
|
||||
},
|
||||
|
||||
/**
|
||||
* Write and filtering the child nodes of this fragment.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter] The filter to use when writing the HTML.
|
||||
* @param {Boolean} [filterRoot] Whether to apply the "root" filter rule specified in the `filter`.
|
||||
*/
|
||||
writeChildrenHtml: function( writer, filter, filterRoot ) {
|
||||
var context = this.getFilterContext();
|
||||
|
||||
// Filtering root if enforced.
|
||||
if ( filterRoot && !this.parent && filter )
|
||||
filter.onRoot( context, this );
|
||||
|
||||
if ( filter )
|
||||
this.filterChildren( filter, false, context );
|
||||
|
||||
for ( var i = 0, children = this.children, l = children.length; i < l; i++ )
|
||||
children[ i ].writeHtml( writer );
|
||||
},
|
||||
|
||||
/**
|
||||
* Execute callback on each node (of a given type) in this document fragment.
|
||||
*
|
||||
* var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p>foo<b>bar</b>bom</p>' );
|
||||
* fragment.forEach( function( node ) {
|
||||
* console.log( node );
|
||||
* } );
|
||||
* // Will log:
|
||||
* // 1. document fragment,
|
||||
* // 2. <p> element,
|
||||
* // 3. "foo" text node,
|
||||
* // 4. <b> element,
|
||||
* // 5. "bar" text node,
|
||||
* // 6. "bom" text node.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {Function} callback Function to be executed on every node.
|
||||
* **Since 4.3.0** if `callback` returned `false` descendants of current node will be ignored.
|
||||
* @param {CKEDITOR.htmlParser.node} callback.node Node passed as argument.
|
||||
* @param {Number} [type] If specified `callback` will be executed only on nodes of this type.
|
||||
* @param {Boolean} [skipRoot] Don't execute `callback` on this fragment.
|
||||
*/
|
||||
forEach: function( callback, type, skipRoot ) {
|
||||
if ( !skipRoot && ( !type || this.type == type ) )
|
||||
var ret = callback( this );
|
||||
|
||||
// Do not filter children if callback returned false.
|
||||
if ( ret === false )
|
||||
return;
|
||||
|
||||
var children = this.children,
|
||||
node,
|
||||
i = 0;
|
||||
|
||||
// We do not cache the size, because the list of nodes may be changed by the callback.
|
||||
for ( ; i < children.length; i++ ) {
|
||||
node = children[ i ];
|
||||
if ( node.type == CKEDITOR.NODE_ELEMENT )
|
||||
node.forEach( callback, type );
|
||||
else if ( !type || node.type == type )
|
||||
callback( node );
|
||||
}
|
||||
},
|
||||
|
||||
getFilterContext: function( context ) {
|
||||
return context || {};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates if line breaks (`br`) should be moved outside inline elements.
|
||||
*
|
||||
* **Note:** This is a global configuration that applies to all instances.
|
||||
*
|
||||
* By default, all children `br` elements, placed at the end of an inline element,
|
||||
* are shifted outside that element. Shifted elements are attached at the end of the parent block element.
|
||||
* It allows producing more clean HTML output without an abundance of
|
||||
* orphaned styling markers. This logic can be changed by disabling shifting line breaks or providing
|
||||
* a custom function allowing to conditionally choose proper behavior.
|
||||
*
|
||||
* * `shiftLineBreaks = true`
|
||||
*
|
||||
* Shift line breaks outside inline element:
|
||||
*
|
||||
* <p><strong>hello, world!<br><br></strong></p>
|
||||
*
|
||||
* will become:
|
||||
*
|
||||
* <p><strong>hello, world!</strong><br><br></p>
|
||||
*
|
||||
* * `shiftLineBreaks = false`
|
||||
*
|
||||
* Keep line breaks inside an inline element:
|
||||
*
|
||||
* <p><strong>hello, world!<br><br></strong></p>
|
||||
*
|
||||
* * `shiftLineBreaks = customFunction`
|
||||
*
|
||||
* Provide a callback function allowing to decide if a line break should be shifted:
|
||||
*
|
||||
* ```javascript
|
||||
* CKEDITOR.config.shiftLineBreaks = function() {
|
||||
* if ( condition ) {
|
||||
* // Shift line break outside element.
|
||||
* return true;
|
||||
* }
|
||||
* // Keep line break inside element.
|
||||
* return false;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* You can also decide to return the {@link CKEDITOR.htmlParser.text} or {@link CKEDITOR.htmlParser.element}
|
||||
* node that will be attached **at the end of the last `br` node** inside an inline element.
|
||||
*
|
||||
* As an example, you may want to add an additional ` ` filler to make sure that a user will be
|
||||
* able to place caret after break lines:
|
||||
*
|
||||
* ```javascript
|
||||
* CKEDITOR.config.shiftLineBreaks = function() {
|
||||
* // Append `nbsp;` character at the end.
|
||||
* return new CKEDITOR.htmlParser.text( ' ' );
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* resulting in:
|
||||
*
|
||||
* <p><strong>hello, world!<br><br> </strong></p>
|
||||
*
|
||||
* @cfg {Boolean/Function} [shiftLineBreaks=true]
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
|
||||
CKEDITOR.config.shiftLineBreaks = true;
|
||||
} )();
|
||||
29
Admin/plugins/ckeditor/core/htmlparser/nameTransformRule.js
Normal file
29
Admin/plugins/ckeditor/core/htmlparser/nameTransformRule.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.htmlParser.nameTransformRule} class
|
||||
* that contains the definition of rule for filtering element names or attribute names. This file is for
|
||||
* documentation purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract class describing the definition of {@link CKEDITOR.htmlParser.filterRulesDefinition} `elementNames` and `attributesNames` filtering rules.
|
||||
*
|
||||
* ```javascript
|
||||
* var rule = [ /^div$/, 'p' ];
|
||||
* ```
|
||||
*
|
||||
* @class CKEDITOR.htmlParser.nameTransformRule
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {RegExp} 0 A regular expression to match the element name or attribute.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {String} 1 A string used to replace the match.
|
||||
*/
|
||||
156
Admin/plugins/ckeditor/core/htmlparser/node.js
Normal file
156
Admin/plugins/ckeditor/core/htmlparser/node.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* A lightweight representation of HTML node.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @class
|
||||
* @constructor Creates a node class instance.
|
||||
*/
|
||||
CKEDITOR.htmlParser.node = function() {};
|
||||
|
||||
CKEDITOR.htmlParser.node.prototype = {
|
||||
/**
|
||||
* Remove this node from a tree.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*/
|
||||
remove: function() {
|
||||
var children = this.parent.children,
|
||||
index = CKEDITOR.tools.indexOf( children, this ),
|
||||
previous = this.previous,
|
||||
next = this.next;
|
||||
|
||||
previous && ( previous.next = next );
|
||||
next && ( next.previous = previous );
|
||||
children.splice( index, 1 );
|
||||
this.parent = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Replace this node with given one.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.node} node The node that will replace this one.
|
||||
*/
|
||||
replaceWith: function( node ) {
|
||||
var children = this.parent.children,
|
||||
index = CKEDITOR.tools.indexOf( children, this ),
|
||||
previous = node.previous = this.previous,
|
||||
next = node.next = this.next;
|
||||
|
||||
previous && ( previous.next = node );
|
||||
next && ( next.previous = node );
|
||||
|
||||
children[ index ] = node;
|
||||
|
||||
node.parent = this.parent;
|
||||
this.parent = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Insert this node after given one.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.node} node The node that will precede this element.
|
||||
*/
|
||||
insertAfter: function( node ) {
|
||||
var children = node.parent.children,
|
||||
index = CKEDITOR.tools.indexOf( children, node ),
|
||||
next = node.next;
|
||||
|
||||
children.splice( index + 1, 0, this );
|
||||
|
||||
this.next = node.next;
|
||||
this.previous = node;
|
||||
node.next = this;
|
||||
next && ( next.previous = this );
|
||||
|
||||
this.parent = node.parent;
|
||||
},
|
||||
|
||||
/**
|
||||
* Insert this node before given one.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.node} node The node that will follow this element.
|
||||
*/
|
||||
insertBefore: function( node ) {
|
||||
var children = node.parent.children,
|
||||
index = CKEDITOR.tools.indexOf( children, node );
|
||||
|
||||
children.splice( index, 0, this );
|
||||
|
||||
this.next = node;
|
||||
this.previous = node.previous;
|
||||
node.previous && ( node.previous.next = this );
|
||||
node.previous = this;
|
||||
|
||||
this.parent = node.parent;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the closest ancestor element of this element which satisfies given condition
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String/Object/Function} condition Name of an ancestor, hash of names or validator function.
|
||||
* @returns {CKEDITOR.htmlParser.element} The closest ancestor which satisfies given condition or `null`.
|
||||
*/
|
||||
getAscendant: function( condition ) {
|
||||
var checkFn =
|
||||
typeof condition == 'function' ?
|
||||
condition :
|
||||
typeof condition == 'string' ?
|
||||
function( el ) {
|
||||
return el.name == condition;
|
||||
} :
|
||||
function( el ) {
|
||||
return el.name in condition;
|
||||
};
|
||||
|
||||
var parent = this.parent;
|
||||
|
||||
// Parent has to be an element - don't check doc fragment.
|
||||
while ( parent && parent.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
if ( checkFn( parent ) )
|
||||
return parent;
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Wraps this element with given `wrapper`.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {CKEDITOR.htmlParser.element} wrapper The element which will be this element's new parent.
|
||||
* @returns {CKEDITOR.htmlParser.element} Wrapper.
|
||||
*/
|
||||
wrapWith: function( wrapper ) {
|
||||
this.replaceWith( wrapper );
|
||||
wrapper.add( this );
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets this node's index in its parent's children array.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @returns {Number}
|
||||
*/
|
||||
getIndex: function() {
|
||||
return CKEDITOR.tools.indexOf( this.parent.children, this );
|
||||
},
|
||||
|
||||
getFilterContext: function( context ) {
|
||||
return context || {};
|
||||
}
|
||||
};
|
||||
} )();
|
||||
70
Admin/plugins/ckeditor/core/htmlparser/text.js
Normal file
70
Admin/plugins/ckeditor/core/htmlparser/text.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* A lightweight representation of HTML text.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.htmlParser.node
|
||||
* @constructor Creates a text class instance.
|
||||
* @param {String} value The text node value.
|
||||
*/
|
||||
CKEDITOR.htmlParser.text = function( value ) {
|
||||
/**
|
||||
* The text value.
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
this.value = value;
|
||||
|
||||
/** @private */
|
||||
this._ = {
|
||||
isBlockLike: false
|
||||
};
|
||||
};
|
||||
|
||||
CKEDITOR.htmlParser.text.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_TEXT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_TEXT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_TEXT,
|
||||
|
||||
/**
|
||||
* Filter this text node with given filter.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
* @returns {Boolean} Method returns `false` when this text node has
|
||||
* been removed. This is an information for {@link CKEDITOR.htmlParser.element#filterChildren}
|
||||
* that it has to repeat filter on current position in parent's children array.
|
||||
*/
|
||||
filter: function( filter, context ) {
|
||||
if ( !( this.value = filter.onText( context, this.value, this ) ) ) {
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the HTML representation of this text to a {CKEDITOR.htmlParser.basicWriter}.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
|
||||
* **Note:** it's unsafe to filter offline (not appended) node.
|
||||
*/
|
||||
writeHtml: function( writer, filter ) {
|
||||
if ( filter )
|
||||
this.filter( filter );
|
||||
|
||||
writer.text( this.value );
|
||||
}
|
||||
} );
|
||||
} )();
|
||||
169
Admin/plugins/ckeditor/core/keystrokehandler.js
Normal file
169
Admin/plugins/ckeditor/core/keystrokehandler.js
Normal file
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Controls keystrokes typing in an editor instance.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a keystrokeHandler class instance.
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
*/
|
||||
CKEDITOR.keystrokeHandler = function( editor ) {
|
||||
if ( editor.keystrokeHandler )
|
||||
return editor.keystrokeHandler;
|
||||
|
||||
/**
|
||||
* A list of keystrokes associated with commands. Each entry points to the
|
||||
* command to be executed.
|
||||
*
|
||||
* Since CKEditor 4 there is no need to modify this property directly during the runtime.
|
||||
* Use {@link CKEDITOR.editor#setKeystroke} instead.
|
||||
*/
|
||||
this.keystrokes = {};
|
||||
|
||||
/**
|
||||
* A list of keystrokes that should be blocked if not defined in
|
||||
* {@link #keystrokes}. In this way it is possible to block the default
|
||||
* browser behavior for those keystrokes.
|
||||
*/
|
||||
this.blockedKeystrokes = {};
|
||||
|
||||
this._ = {
|
||||
editor: editor
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
( function() {
|
||||
var cancel;
|
||||
|
||||
var onKeyDown = function( event ) {
|
||||
// The DOM event object is passed by the "data" property.
|
||||
event = event.data;
|
||||
|
||||
var keyCombination = event.getKeystroke();
|
||||
var command = this.keystrokes[ keyCombination ];
|
||||
var editor = this._.editor;
|
||||
|
||||
cancel = ( editor.fire( 'key', { keyCode: keyCombination, domEvent: event } ) === false );
|
||||
|
||||
if ( !cancel ) {
|
||||
if ( command ) {
|
||||
var data = { from: 'keystrokeHandler' };
|
||||
cancel = ( editor.execCommand( command, data ) !== false );
|
||||
}
|
||||
|
||||
if ( !cancel )
|
||||
cancel = !!this.blockedKeystrokes[ keyCombination ];
|
||||
}
|
||||
|
||||
if ( cancel )
|
||||
event.preventDefault( true );
|
||||
|
||||
return !cancel;
|
||||
};
|
||||
|
||||
var onKeyPress = function( event ) {
|
||||
if ( cancel ) {
|
||||
cancel = false;
|
||||
event.data.preventDefault( true );
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.keystrokeHandler.prototype = {
|
||||
/**
|
||||
* Attaches this keystroke handle to a DOM object. Keystrokes typed
|
||||
* over this object will be handled by this keystrokeHandler.
|
||||
*
|
||||
* @param {CKEDITOR.dom.domObject} domObject The DOM object to attach to.
|
||||
*/
|
||||
attach: function( domObject ) {
|
||||
// For most browsers, it is enough to listen to the keydown event
|
||||
// only.
|
||||
domObject.on( 'keydown', onKeyDown, this );
|
||||
|
||||
// Some browsers instead, don't cancel key events in the keydown, but in the
|
||||
// keypress. So we must do a longer trip in those cases.
|
||||
if ( CKEDITOR.env.gecko && CKEDITOR.env.mac )
|
||||
domObject.on( 'keypress', onKeyPress, this );
|
||||
}
|
||||
};
|
||||
} )();
|
||||
|
||||
/**
|
||||
* A list associating keystrokes with editor commands. Each element in the list
|
||||
* is an array where the first item is the keystroke, and the second is the
|
||||
* name of the command to be executed.
|
||||
*
|
||||
* This setting should be used to define (as well as to overwrite or remove) keystrokes
|
||||
* set by plugins (like `link` and `basicstyles`). If you want to set a keystroke
|
||||
* for your plugin or during the runtime, use {@link CKEDITOR.editor#setKeystroke} instead.
|
||||
*
|
||||
* Since default keystrokes are set by the {@link CKEDITOR.editor#setKeystroke}
|
||||
* method, by default `config.keystrokes` is an empty array.
|
||||
*
|
||||
* See {@link CKEDITOR.editor#setKeystroke} documentation for more details
|
||||
* regarding the start up order.
|
||||
*
|
||||
* // Change default Ctrl+L keystroke for 'link' command to Ctrl+Shift+L.
|
||||
* config.keystrokes = [
|
||||
* ...
|
||||
* [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 76, 'link' ], // Ctrl+Shift+L
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* To reset a particular keystroke, the following approach can be used:
|
||||
*
|
||||
* // Disable default Ctrl+L keystroke which executes the 'link' command by default.
|
||||
* config.keystrokes = [
|
||||
* ...
|
||||
* [ CKEDITOR.CTRL + 76, null ], // Ctrl+L
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* In order to reset all default keystrokes, a {@link CKEDITOR#instanceReady} callback should be
|
||||
* used. This is since editor defaults are merged rather than overwritten by
|
||||
* user keystrokes.
|
||||
*
|
||||
* **Note**: This can be potentially harmful for the editor. Avoid this unless you are
|
||||
* aware of the consequences.
|
||||
*
|
||||
* // Reset all default keystrokes.
|
||||
* config.on.instanceReady = function() {
|
||||
* this.keystrokeHandler.keystrokes = [];
|
||||
* };
|
||||
*
|
||||
* @cfg {Array} [keystrokes=[]]
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when any keyboard key (or a combination thereof) is pressed in the editing area.
|
||||
*
|
||||
* editor.on( 'key', function( evt ) {
|
||||
* if ( evt.data.keyCode == CKEDITOR.CTRL + 90 ) {
|
||||
* // Do something...
|
||||
*
|
||||
* // Cancel the event, so other listeners will not be executed and
|
||||
* // the keydown's default behavior will be prevented.
|
||||
* evt.cancel();
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* Usually you will want to use the {@link CKEDITOR.editor#setKeystroke} method or
|
||||
* the {@link CKEDITOR.config#keystrokes} option to attach a keystroke to some {@link CKEDITOR.command command}.
|
||||
* Key event listeners are usuful when some action should be executed conditionally, based
|
||||
* for example on precise selection location.
|
||||
*
|
||||
* @event key
|
||||
* @member CKEDITOR.editor
|
||||
* @param data
|
||||
* @param {Number} data.keyCode A number representing the key code (or a combination thereof).
|
||||
* It is the sum of the current key code and the {@link CKEDITOR#CTRL}, {@link CKEDITOR#SHIFT}
|
||||
* and {@link CKEDITOR#ALT} constants, if those are pressed.
|
||||
* @param {CKEDITOR.dom.event} data.domEvent A `keydown` DOM event instance. Available since CKEditor 4.4.1.
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
*/
|
||||
103
Admin/plugins/ckeditor/core/lang.js
Normal file
103
Admin/plugins/ckeditor/core/lang.js
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Stores language-related functions.
|
||||
*
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.lang = {
|
||||
/**
|
||||
* The list of languages available in the editor core.
|
||||
*
|
||||
* alert( CKEDITOR.lang.languages.en ); // 1
|
||||
*/
|
||||
languages: {
|
||||
af: 1, ar: 1, az: 1, bg: 1, bn: 1, bs: 1, ca: 1, cs: 1, cy: 1, da: 1, de: 1, 'de-ch': 1, el: 1,
|
||||
'en-au': 1, 'en-ca': 1, 'en-gb': 1, en: 1, eo: 1, es: 1, 'es-mx':1, et: 1, eu: 1, fa: 1, fi: 1, fo: 1,
|
||||
'fr-ca': 1, fr: 1, gl: 1, gu: 1, he: 1, hi: 1, hr: 1, hu: 1, id: 1, is: 1, it: 1, ja: 1, ka: 1,
|
||||
km: 1, ko: 1, ku: 1, lt: 1, lv: 1, mk: 1, mn: 1, ms: 1, nb: 1, nl: 1, no: 1, oc: 1, pl: 1, 'pt-br': 1,
|
||||
pt: 1, ro: 1, ru: 1, si: 1, sk: 1, sl: 1, sq: 1, 'sr-latn': 1, sr: 1, sv: 1, th: 1, tr: 1, tt: 1, ug: 1,
|
||||
uk: 1, vi: 1, 'zh-cn': 1, zh: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* The list of languages that are written Right-To-Left (RTL) and are supported by the editor.
|
||||
*/
|
||||
rtl: { ar: 1, fa: 1, he: 1, ku: 1, ug: 1 },
|
||||
|
||||
/**
|
||||
* Loads a specific language file, or auto detects it. A callback is
|
||||
* then called when the file gets loaded.
|
||||
*
|
||||
* @param {String} languageCode The code of the language file to be
|
||||
* loaded. If null or empty, autodetection will be performed. The
|
||||
* same happens if the language is not supported.
|
||||
* @param {String} defaultLanguage The language to be used if
|
||||
* `languageCode` is not supported or if the autodetection fails.
|
||||
* @param {Function} callback A function to be called once the
|
||||
* language file is loaded. Two parameters are passed to this
|
||||
* function: the language code and the loaded language entries.
|
||||
*/
|
||||
load: function( languageCode, defaultLanguage, callback ) {
|
||||
// If no languageCode - fallback to browser or default.
|
||||
// If languageCode - fallback to no-localized version or default.
|
||||
if ( !languageCode || !CKEDITOR.lang.languages[ languageCode ] )
|
||||
languageCode = this.detect( defaultLanguage, languageCode );
|
||||
|
||||
var that = this,
|
||||
loadedCallback = function() {
|
||||
that[ languageCode ].dir = that.rtl[ languageCode ] ? 'rtl' : 'ltr';
|
||||
callback( languageCode, that[ languageCode ] );
|
||||
};
|
||||
|
||||
if ( !this[ languageCode ] )
|
||||
CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( 'lang/' + languageCode + '.js' ), loadedCallback, this );
|
||||
else
|
||||
loadedCallback();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the language that best fits the user language. For example,
|
||||
* suppose that the user language is "pt-br". If this language is
|
||||
* supported by the editor, it is returned. Otherwise, if only "pt" is
|
||||
* supported, it is returned instead. If none of the previous are
|
||||
* supported, a default language is then returned.
|
||||
*
|
||||
* alert( CKEDITOR.lang.detect( 'en' ) ); // e.g., in a German browser: 'de'
|
||||
*
|
||||
* @param {String} defaultLanguage The default language to be returned
|
||||
* if the user language is not supported.
|
||||
* @param {String} [probeLanguage] A language code to try to use,
|
||||
* instead of the browser-based autodetection.
|
||||
* @returns {String} The detected language code.
|
||||
*/
|
||||
detect: function( defaultLanguage, probeLanguage ) {
|
||||
var languages = this.languages;
|
||||
probeLanguage = probeLanguage || navigator.userLanguage || navigator.language || defaultLanguage;
|
||||
|
||||
var parts = probeLanguage.toLowerCase().match( /([a-z]+)(?:-([a-z]+))?/ ),
|
||||
lang = parts[ 1 ],
|
||||
locale = parts[ 2 ];
|
||||
|
||||
if ( languages[ lang + '-' + locale ] )
|
||||
lang = lang + '-' + locale;
|
||||
else if ( !languages[ lang ] )
|
||||
lang = null;
|
||||
|
||||
CKEDITOR.lang.detect = lang ?
|
||||
function() {
|
||||
return lang;
|
||||
} : function( defaultLanguage ) {
|
||||
return defaultLanguage;
|
||||
};
|
||||
|
||||
return lang || defaultLanguage;
|
||||
}
|
||||
};
|
||||
|
||||
} )();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user