در این سوال قصد داریم به طراحی یک **متنخوان** بپردازیم. متنخوان این قابلیت را فراهم میکند تا هنگام مطالعهی یک متن، بخشهای مهم آن را با رنگ مورد نظر خود مشخص کنید، یا روی قسمتهایی از متن یادداشت قرار دهید. بخش عمدهای از متنخوان از قبل پیادهسازی شده است. شما باید پس از درک پیادهسازیهای اولیه، یک فایل با نام `Text.js` را به نحوی تغییر دهید که در کنار سایر فایلها، نتیجهی مورد نظر را به نمایش بگذارد.
#### امکانات متنخوان
+ یک متنخوان دارای سه دکمه برای اعمال رنگهای قرمز، زرد، و سبز، و یک دکمه برای پاککردن رنگ است. با انتخاب متن و سپس کلیک بر روی دکمهی رنگ، متن مورد نظر با آن رنگ مشخص خواهد شد. همچنین با انتخاب یک قسمت از متن و فشردن دکمهی پاککن، آن قسمت از متن به حالت عادی برمیگردد. اگر قسمتی از متن که انتخاب میکنیم از قبل رنگی شده باشد، رنگ جدید جای آن را خواهد گرفت. به مراحل مثال زیر دقت کنید.
![توضیح تصویر](http://bayanbox.ir/view/480394134426311538/tools-1-rsz.gif)
+ با کلیک بر روی دکمهی پنجم که با علامت `+` مشخص شده است، فرم یادداشتگذاری ظاهر میشود. برای یادداشتگذاری، ابتدا یادداشت موردنظر وارد میشود؛ سپس قسمت مربوط به یادداشت در متن انتخاب میشود. با کلیک بر روی دکمهی `Add` ، یادداشت به آن قسمت اضافه میشود. برای ظاهرشدن یا ناپدیدشدن یادداشت هر قسمت، باید روی آن قسمت کلیک کرد. از پاککن در مورد یادداشتها نیز میتوان استفاده کرد. همچنین اگر یادداشت جدید بر روی قسمتهایی که از قبل رنگی شدهاند یا یادداشت داشتهاند قرار بگیرد، جای آنها را میگیرد.
+ اگر متن دو یادداشت به گونهای انتخاب شوند که به هم وصل شوند، محتوای یادداشت آن دو با یکدیگر ادغام میشود.
+ اگر متن یک یادداشت را با پاککن به دو قسمت تقسیم کنیم، هر قسمت جدید دارای همان یادداشت قبلی خواهد بود. به مراحل مثال زیر دقت کنید.
![توضیح تصویر](http://bayanbox.ir/view/7249643462710967390/tools-2-rsz.gif)
# فایلهای اولیه
فایلهای اولیهی پروژه را از [اینجا](http://s9.picofile.com/file/8340255526/highlighter_initial.zip.html) دانلود کنید. ساختار این فایلها به شرح زیر است (مواردی که نیاز به تغییر دارند با `*` مشخص شدهاند):
```
highlighter.zip
├── public
│ └── index.html
├── src
| ├── Components
│ │ ├── ActionButtons.js
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── Content.css
│ │ ├── Content.js
│ │ ├── Highlighter.js
│ │ └── Text.js *
│ └── index.js
├── package.json
└── package-lock.json
```
# راه اندازی پروژه
**برای اجرای پروژه، باید `Node.js` و `npm` را از قبل نصب کرده باشید.**
+ ابتدا فایلهای اولیه را دانلود و از حالت فشرده خارج کنید.
+ سپس در پوشهی `highlighter` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
+ سپس در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
+ پس از انجام موفق این مراحل، با مراجعه به آدرس `http://localhost:3000/` میتوانید نتیجهی کد را ببینید.
# جزئیات
مطالعهی فایلهای اولیه و درک نحوهی کارکرد آنها بخشی از حل سوال است؛ اما برای تکمیل فایل `Text.js` شما به استفادهی مستقیم از دو عنصر زیر که در فایل `Highlighter.js` پیادهسازی شدهاند، احتیاج خواهید داشت:
+ **`Highlight` :** این عنصر با دریافت سه ویژگی شناسه (`id`)، نوع (`type`)، و متن (`text`)، یک قسمت رنگی با شناسه و رنگ مربوط به نوع موردنظر میسازد که متن دریافتشده را به نمایش میگذارد. انواع مختلف این عنصر با اختصاص مقادیر زیر به ویژگی `type` بهدست میآیند:
+ `red` : این مقدار، قسمت رنگی با پسزمینهی قرمز ایجاد میکند.
+ `yellow` : این مقدار، قسمت رنگی با پسزمینهی زرد ایجاد میکند.
+ `green` : این مقدار، قسمت رنگی با پسزمینهی سبز ایجاد میکند.
+ `transparent` : این مقدار، قسمت رنگی با پسزمینهی سفید ایجاد میکند.
+ **`Note` :** این عنصر با دریافت شناسه (`id`)، متن (`text`)، و یادداشت (`note`)، متن موردنظر را با یادداشت و شناسهی دریافتشده به نمایش میگذارد. این عنصر قابلیت تغییر وضیت نمایش یادداشت همراه با کلیک را نیز پیادهسازی میکند.
شما باید با استفاده از این دو عنصر، **تمام** بخشهای مختلف متن را کنار یکدیگر قرار دهید تا هر بخش با رنگ، یا یادداشت منتسب به خود به نمایش دربیاید. برای این منظور، هر قسمت از متن باید با شناسهای به شکل `index_i_j` بارگذاری شود؛ به طوریکه `i` اندیش شروع متن در رشتهی اصلی، و `j` جایگاه پایان آن است. **منظور از رشتهی اصلی، کل متن هدف است.** به مثال زیر توجه کنید:
![توضیح تصویر](http://bayanbox.ir/view/4272345597407743999/last-example-rsz.png)
برای این منظور، باید عناصر زیر با ویژگیهای منسوب به هر کدام، و با همین ترتیب، **در داخل `<div></div>` بارگذاریشده** در `Text.js` قرار بگیرند:
```js
Highlight: {
id: 'index_0_27',
type: 'transparent',
text: 'Lorem ipsum dolor sit amet,'
}
Note: {
id: 'index_27_57',
text: ' consectetuer adipiscing elit.',
note: 'Sample note'
}
Highlight: {
id: 'index_57_362',
type: 'transparent',
text: ' Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. '
}
Highlight: {
id: 'index_362_488',
type: 'red',
text: 'In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt.'
}
Highlight: {
id: 'index_488_868',
type: 'transparent',
text: ' Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.'
}
```
+ اگر در تصویر فوق هیچ قسمت رنگی یا یادداشتی موجود نباشد، باز هم انتظار میرود که کل متن در یک قسمت رنگی با زمینهی سفید، و شناسهی `#index_0_868` بارگذاری شود.
+ هنگام ادغام متن دو یادداشت، اگر محتوای یادداشت عنصر اول را `note_1` ، و محتوای یادداشت عنصر دوم را `note_2` بنامیم، محتوای یادداشت نهایی به صورت زیر خواهد بود:
```js
note = note_1 + '\n' + note_2;
```
+ زمانیکه یک قسمت با قسمت پیشین خود همنوع باشد (چه از نوع رنگی و چه از نوع یادداشت)، با آن ادغام شده و به یک قسمت جدید تبدیل میشود. در واقع این قسمت جدید، اجتماع دو قسمت قبلی است که در قالب یک عنصر نمایش داده میشود.
+ بازهها ممکن است از انتها به ابتدا انتخاب شوند.
برای مشاهدهی حالتهای پیچیدهتر، به گیفهای ابتدای سوال دقت کنید. درهر حالت، پس از تکمیل تغییر موردنظر، انتظار خواهیم داشت تا عناصر به صورت گفتهشده در فایل `Text.js` قرار بگیرند. تغییرات دریافتشده از کاربر به صورت ورودیهای تابع `get_new_input(start_id, end_id, start_index, end_index, tag, note)` در اختیار شما قرار خواهند گرفت. برای آشنایی با این ویژگیها، فایل `App.js` را مطالعه کنید.
# نکات
+ داوری بر اساس شناسه (`id`) صورت میگیرد؛ بنابراین دقیقا از شکل تعریفشده استفاده کنید.
+ داوری به شکل اجرای سناریوهای مختلف انتخاب روی یک متن دلخواه انجام میشود؛ بنابراین اشتباه در بارگذاری صحیح عناصر یا پیادهسازی نادرست بخشی از تابع گفتهشده میتواند منجر به اتلاف بخش عمدهای از امتیاز شما شود.
+ پس از اعمال تغییرات، کل پروژه را طبق ساختار زیر _zip_ کرده و ارسال کنید. دقت کنید که پوشه `node_modules` در فایل ارسالی نباشد.
+ پروژه را با ساختار زیر ارسال کنید:
```
[your-zip-file-name].zip
├── public
│ └── index.html
├── src
| ├── Components
│ │ ├── ActionButtons.js
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── Content.css
│ │ ├── Content.js
│ │ ├── Highlighter.js
│ │ └── Text.js
│ └── index.js
├── package.json
└── package-lock.json
```
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.