عداد وكاشف الكلمات المكررة
document.addEventListener(‘DOMContentLoaded’, () => {
const inputText = document.getElementById(‘inputText’);
const charCount = document.getElementById(‘charCount’);
const wordCount = document.getElementById(‘wordCount’);
const repeatedCount = document.getElementById(‘repeatedCount’);
const paragraphCount = document.getElementById(‘paragraphCount’);
const highlightedText = document.getElementById(‘highlightedText’);
const clearBtn = document.getElementById(‘clearBtn’);
const themeToggle = document.getElementById(‘themeToggle’);
let debounceTimer;
const clearText = () => {
inputText.value = ”;
highlightedText.innerHTML = ‘النص المحلل سيظهر هنا…’;
charCount.textContent = ‘0’;
wordCount.textContent = ‘0’;
repeatedCount.textContent = ‘0’;
paragraphCount.textContent = ‘0’;
inputText.focus();
};
if (clearBtn) {
clearBtn.addEventListener(‘click’, clearText);
}
const analyzeText = () => {
const text = inputText.value;
// عدد الأحرف بدون المسافات
const charactersWithoutSpaces = text.replace(/\s/g, ”);
charCount.textContent = charactersWithoutSpaces.length;
// تقسيم النص إلى كلمات
const words = text.trim()
.split(/[\s\n]+/)
.filter(word => word.length > 0);
wordCount.textContent = words.length;
// عدد الفقرات
const paragraphs = text.split(/\n\s*\n/);
paragraphCount.textContent = text.trim() === ” ? 0 : paragraphs.length;
// البحث عن الكلمات المكررة
const wordMap = {};
words.forEach(word => {
const cleanWord = word.replace(/[.,!؟،؛()[\]{}'”]/g, ”).trim();
if (cleanWord.length > 1) {
wordMap[cleanWord] = (wordMap[cleanWord] || 0) + 1;
}
});
// عدد الكلمات المكررة
const repeatedWords = Object.entries(wordMap).filter(([_, count]) => count > 1);
repeatedCount.textContent = repeatedWords.length;
// تمييز الكلمات المكررة
let highlightedContent = text;
repeatedWords.sort(([a], [b]) => b.length – a.length);
repeatedWords.forEach(([word, count]) => {
const regex = new RegExp(`(^|\\s)(${word})(\\s|$|[.,!؟،؛:])`, ‘gm’);
highlightedContent = highlightedContent.replace(
regex,
`$1
$2 $3`
);
});
highlightedText.innerHTML = highlightedContent || ‘النص المحلل سيظهر هنا…’;
};
// استخدام debounce لتحسين الأداء
const debouncedAnalyze = () => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(analyzeText, 300);
};
inputText.addEventListener(‘input’, debouncedAnalyze);
// التحليل الأولي
analyzeText();
// التحقق من وجود تفضيل محفوظ
const savedTheme = localStorage.getItem(‘theme’);
// تطبيق السمة المحفوظة إذا كانت “dark” فقط
if (savedTheme === ‘dark’) {
document.documentElement.setAttribute(‘data-theme’, ‘dark’);
}
// دالة تبديل السمة
const toggleTheme = () => {
const currentTheme = document.documentElement.getAttribute(‘data-theme’);
const newTheme = currentTheme === ‘dark’ ? ‘light’ : ‘dark’;
if (newTheme === ‘dark’) {
document.documentElement.setAttribute(‘data-theme’, ‘dark’);
localStorage.setItem(‘theme’, ‘dark’);
} else {
document.documentElement.removeAttribute(‘data-theme’);
localStorage.setItem(‘theme’, ‘light’);
}
};
// إضافة مستمع الحدث لزر تبديل السمة
themeToggle.addEventListener(‘click’, toggleTheme);
});
:root {
–primary-color: #ffb200;
–secondary-color: #ffb200;
–background-color: #ecf0f1;
–container-bg: #ffffff;
–text-color: #333333;
–box-shadow: 0 4px 6px rgba(255, 178, 0, 0.2);
–stat-box-bg: #ffffff;
–input-bg: #ffffff;
–input-border: #ddd;
–transition: all 0.3s ease;
}
[data-theme=”dark”] {
–primary-color: #ffb200;
–secondary-color: #ffb200;
–background-color: #1a1a1a;
–container-bg: #2d2d2d;
–text-color: #ffffff;
–stat-box-bg: #3d3d3d;
–input-bg: #2d2d2d;
–input-border: #4d4d4d;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: ‘Cairo’, sans-serif;
}
html {
font-size: 16px;
}
body {
font-family: ‘Cairo’, sans-serif;
margin: 0;
padding: clamp(10px, 3vw, 20px);
background-color: var(–background-color);
min-height: 100vh;
overflow-x: hidden;
color: var(–text-color);
}
.container {
max-width: min(1000px, 95%);
margin: 0 auto;
background-color: var(–container-bg);
padding: clamp(15px, 3vw, 30px);
border-radius: 15px;
box-shadow: var(–box-shadow);
}
.site-header {
text-align: center;
margin-bottom: clamp(20px, 5vw, 40px);
color: var(–primary-color);
}
.site-header h1 {
margin: 0;
font-size: clamp(1.5rem, 4vw, 2.5rem);
animation: fadeIn 1s ease;
color: var(–primary-color);
}
.subtitle {
color: #666;
margin-top: 10px;
font-size: clamp(0.9rem, 2vw, 1.1rem);
}
.text-input-container {
position: relative;
margin-bottom: clamp(20px, 4vw, 30px);
}
.text-area {
width: 100%;
height: clamp(150px, 30vh, 300px);
padding: 15px;
border: 2px solid var(–input-border);
border-radius: 10px;
resize: vertical;
direction: rtl;
font-size: clamp(14px, 2vw, 16px);
transition: var(–transition);
background-color: var(–input-bg);
color: var(–text-color);
font-family: ‘Cairo’, sans-serif;
}
.text-area:focus {
border-color: var(–primary-color);
box-shadow: 0 0 0 3px rgba(255, 178, 0, 0.2);
outline: none;
}
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
gap: clamp(10px, 2vw, 20px);
margin-bottom: clamp(20px, 4vw, 30px);
}
.stat-box {
background-color: var(–stat-box-bg);
padding: clamp(15px, 3vw, 20px);
border-radius: 10px;
text-align: center;
transition: var(–transition);
border: 1px solid rgba(255, 178, 0, 0.2);
}
.stat-box:hover {
box-shadow: 0 5px 15px rgba(255, 178, 0, 0.2);
}
.stat-box i {
font-size: clamp(18px, 3vw, 24px);
color: #000000;
margin-bottom: 10px;
}
.stat-box h3 {
margin: 10px 0;
color: #000000;
font-size: clamp(14px, 2vw, 16px);
font-family: ‘Cairo’, sans-serif;
font-weight: 600;
}
.count {
font-size: clamp(18px, 3vw, 24px);
font-weight: bold;
color: #000000;
font-family: ‘Cairo’, sans-serif;
font-weight: 700;
}
.result-container {
background-color: var(–stat-box-bg);
padding: clamp(15px, 3vw, 20px);
border-radius: 10px;
margin-top: clamp(20px, 4vw, 30px);
border: 1px solid rgba(255, 178, 0, 0.2);
}
.result-container h2 {
color: var(–primary-color);
margin-top: 0;
margin-bottom: clamp(15px, 3vw, 20px);
font-size: clamp(16px, 2.5vw, 20px);
}
.highlighted-text {
white-space: pre-wrap;
line-height: 1.6;
padding: clamp(10px, 2vw, 15px);
background-color: white;
border-radius: 8px;
min-height: 100px;
font-family: inherit;
direction: rtl;
text-align: right;
font-size: clamp(14px, 2vw, 16px);
overflow-wrap: break-word;
word-wrap: break-word;
}
.highlighted-text br {
display: block;
margin: 0.5em 0;
}
.repeated {
background-color: rgba(255, 178, 0, 0.15);
padding: 2px 4px;
border-radius: 3px;
transition: var(–transition);
border: 1px solid rgba(255, 178, 0, 0.2);
}
.repeated:hover {
background-color: rgba(255, 178, 0, 0.25);
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (max-width: 480px) {
.stats {
grid-template-columns: 1fr;
}
.stat-box {
padding: 12px;
}
}
@media (min-width: 481px) and (max-width: 768px) {
.stats {
grid-template-columns: repeat(2, 1fr);
}
}
@media (hover: none) {
.stat-box:hover {
transform: none;
}
}
@media print {
body {
background: white;
padding: 0;
}
.container {
box-shadow: none;
padding: 0;
}
}
.clear-btn {
position: absolute;
bottom: 10px;
left: 10px;
padding: 8px 16px;
background-color: var(–primary-color);
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
transition: all 0.3s ease;
font-family: ‘Cairo’, ‘Segoe UI’, Tahoma, sans-serif;
font-size: 14px;
display: flex;
align-items: center;
gap: 6px;
box-shadow: 0 2px 4px rgba(255, 178, 0, 0.2);
}
.clear-btn:hover {
background-color: #e6a000;
box-shadow: 0 4px 8px rgba(255, 178, 0, 0.3);
}
.clear-btn:active {
transform: translateY(0);
}
.clear-btn i {
font-size: 16px;
}
@media (max-width: 768px) {
.clear-btn {
padding: 6px 12px;
font-size: 12px;
}
.clear-btn i {
font-size: 14px;
}
}
a {
color: var(–primary-color);
}
a:hover {
color: #e6a000;
}
::selection {
background-color: rgba(255, 178, 0, 0.2);
color: var(–text-color);
}
.text-area::placeholder {
color: #6f757b;
opacity: 1;
}
.text-area::-webkit-input-placeholder {
color: #6f757b;
}
.text-area::-moz-placeholder {
color: #6f757b;
opacity: 1;
}
.text-area:-ms-input-placeholder {
color: #6f757b;
}
.text-area:-moz-placeholder {
color: #6f757b;
opacity: 1;
}
.theme-toggle {
position: fixed;
bottom: 20px;
right: 20px;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: var(–primary-color);
border: none;
cursor: pointer;
box-shadow: var(–box-shadow);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
transition: var(–transition);
}
.theme-toggle:hover {
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(255, 178, 0, 0.3);
}
.theme-toggle i {
font-size: 1.5rem;
color: #ffffff;
}
.theme-toggle .light-icon {
display: none;
}
.theme-toggle .dark-icon {
display: block;
}
[data-theme=”dark”] .theme-toggle .light-icon {
display: block;
}
[data-theme=”dark”] .theme-toggle .dark-icon {
display: none;
}
[data-theme=”dark”] .highlighted-text {
background-color: var(–input-bg);
color: var(–text-color);
}
[data-theme=”dark”] .result-container {
background-color: var(–stat-box-bg);
}
@media (max-width: 768px) {
.theme-toggle {
bottom: 10px;
right: 10px;
width: 40px;
height: 40px;
}
.theme-toggle i {
font-size: 1.2rem;
}
}
/* تحديث أنماط الفوتر */
.footer {
text-align: center;
padding: 20px 0;
margin-top: 40px;
border-top: 1px solid var(–input-border);
position: relative;
width: 100%;
}
.footer-content {
display: flex;
justify-content: center;
align-items: center;
}
.footer p {
margin: 0;
color: var(–text-color);
font-size: 14px;
font-weight: 500;
}
/* تحسين المسافات للشاشات الصغيرة */
@media (max-width: 768px) {
.footer {
margin-top: 30px;
padding: 15px 0;
}
.footer p {
font-size: 13px;
}
}