SmartEditor™ 공개 프로젝트 리뷰.
2008년 12월 31일 스마트에디터가 세상에 공개 되었습니다. 알파 버전(공개 테스트용 버전)으로써 잘 드러나지 않는 버그가 남아 있지만 개선되는 것은 시간문제 입니다. 스마트에디터는 곧 안정화 되는대로 ‘XE‘의 기본 에디터로도 탑재될 예정입니다. 제가 참여한 부분은 UI개발 분야로써 기존에 네이버에서 사용되고 있던 스마트 에디터의 HTML/CSS 레거시 코드를 사용하지 않고 완전히 새롭게 만들었습니다. ‘SmartEditor Basic’은 ‘Naver SmartEditor’와 서로 다른 버전의 ‘Javascript Library’를 사용하고 있으며 포함된 스펙이나 HTML/CSS 코드 및 Accessibility 성능도 확연히 다릅니다. 사실상 SmartEditor라는 이름과 디자인만 공유하고 있을 뿐 보이지 않는 부분은 완전히 다르다는 거죠.
- Demo : SmartEditor Basic 데모 확인.
- HTML : CSS가 제거된 순수 HTML.
- default.css : 에디터용 스타일 시트.
- style.css : 콘텐츠용 스타일 시트. 스마트에디터에서 작성한 문서가 출력되는 곳에 필요.
- Output : 스마트에디터를 이용하여 작성된 페이지 서식 예.
- Download : SmartEditor Basic 최신버전 내려받기.
다른 에디터와 구별되는 특징.
| Korea | Global | ||||||
|---|---|---|---|---|---|---|---|
| Brand | SmartEditor Basic | Naver SmartEditor | Daum Editor | OpenMaru Xquard | FCKeditor | TinyMCE | markItUp |
| License | LGPL | NHN Corp. | Daum Corp. | LGPL | CDL | LGPL | MIT/GPL |
| Demo | Yes | None | None | Yes | Yes | Yes | Yes |
| Cross Browser | IE/FF/CR/SF/OP | IE/FF/CR/OP | IE/FF/CR/SF/OP | IE/FF/CR/SF/OP | IE/FF/CR/SF/OP | IE/FF/CR/SF/OP | IE/FF/CR/SF/OP |
기존의 네이버 카페, 블로그 등에 사용된 스마트에디터는 Safari 브라우저의 글쓰기를 지원하지 못했으나 현재 공개된 버전은 Safari를 포함하여 대중적인 브라우저에서 모두 글쓰기가 가능 합니다. 또한 LGPL 라이선스를 적용하여 코드 안에 저작권 명시와 수정된 라이브러리를 공개해야 한다는 조건만 지키면 상업적으로 거의 아무런 제한이 없이 사용이 가능한 실로 유용한 제품 이라고 생각합니다. 전 세계적으로 사랑받고 있는 다른 에디터와 비교하면 현재로써는 글쓰기에 필요하다고 판단되는 최소한의 스펙만을 포함하고 있지만 라이선스를 공개한 이상 그 확장 가능성은 무궁무진 합니다. 필요한 사람은 얼마든지 자유롭게 가져다가 모든 목적으로 사용한 후 다시 사회에 환원하면 됩니다.
기존 스마트에디터와 구별되는 특징.
기존의 네이버 스마트에디터보다 공개된 스펙이 더 가볍고 견고하게 설계됨. 확장 가능성과 접근성 문제도 해결됨.
| Naver SmartEditor | SmartEditor Basic | |
|---|---|---|
| Design/Layout | 디자인된 드롭다운 메뉴 레이어 사용. 고정폭 레이아웃. | 드롭 다운 메뉴에 브라우저 기본 콘트롤 사용. 가변폭 레이아웃 사용. 현재 데모는 고정폭이나 가변폭으로 변경 가능하고 브라우저 크기를 극단적으로 줄이는 경우 편집 도구모음이 다단으로 흐름. |
| HTML/CSS | 레이아웃을 위한 테이블 사용 등 표현을 위한 마크업이 사용됨. 브라우저 호환성 문제를 해결하는데 주력. 전경 이미지 기법 사용으로 대부분의 버튼들이 서로 잘게 분리되어 있어 http 요청이 많음. 이미지 예. 스킨 변경시 HTML/CSS 코드를 모두 수정해야 함. | 기존의 레거시 코드를 모두 제거하고 처음부터 다시 제작. 브라우저 호환성 문제뿐만 아니라 웹 표준 기반의 의미론적 마크업 준수. 이미지를 모두 배경으로 처리하는 IRImage Replacement 기법과 Image Sprites 기법을 사용하여 http 요청을 최소화. 이미지 예. 스킨 변경시 CSS 코드만 수정하면 됨. |
| Javascript | 자체 개발 Jindo1 Framework 미공개 버전사용. 오픈소스 아님. | 자체 개발 Jindo Framework(LGPL) 사용. |
| Accessibility | 콘텐츠 배치 순서가 논리적이지 않음. 편집 도구모음에 키보드 접근 불가. 편집창에 한번 들어가게 되면 키보드만으로 빠져나올 수 없음. | 콘텐츠 배치 순서가 논리적이며 모든 항목을 키보드로 제어 가능. 편집 도구모음을 건너 뛸 수 있는 숨은 링크 사용. 키보드만으로 편집창에서 빠져나올 수 있음. |
| Performance | 네이버 DB활용을 극대화 하도록 최적화 되어 있어 공개버전에 비하여 다소 무거울 것으로 추정됨. | 네이버 DB 첨부기능이 모두 빠지고 순수하게 글쓰기에 필요한 기능만 포함되어 있어 가볍고 빠름. |
| Extensibility | 현재는 특정 서비스에 최적화 되어 있기 때문에 차기 버전 제작시 레거시 코드를 버리는 편이 비용이 적게 들어갈 것으로 예상됨. | 차기 버전 제작시 레거시 코드를 재활용 하는것이 비용이 적게 들어갈 것으로 예상됨. 확장 가능성이 높음. |
키보드 조작을 위한 단축키 지원 현황.
OS단에서 기본적으로 제공하는 단축키와 스마트에디터가 추가로 지원하는 단축키 정리. 취소선은 아직 구현되지 않았거나 구현을 포기한 기능.
| 단축키 제공 주체 | 단축키 조합 | 명령 |
|---|---|---|
| OS 제공 단축키 | Ctrl+Z | 되돌리기 |
| Ctrl+Y | 재실행 | |
| Ctrl+X | 잘라내기 | |
| Ctrl+C | 복사하기 | |
| Ctrl+A | 전체선택 | |
| Ctrl+F | 찾기 | |
| Right(→) | 다음 글자로 커서 이동 | |
| Left(←) | 이전 글자로 커서 이동 | |
| Ctrl+Right(→) | 다음 단어로 커서 이동 | |
| Ctrl+Left(←) | 이전 단어로 커서 이동 | |
| Ctrl+Shift+Right(→) | 다음 단어 블럭 지정 | |
| Ctrl+Shift+Left(←) | 이전 단어 블럭 지정 | |
| 스마트에디터 지원 단축키 | Ctrl+B | 굵은 글꼴 |
| Ctrl+U | 밑줄 | |
| Ctrl+I | 기울임 글꼴 | |
사용자 인터렉션 제어를 위한 HTML/CSS 가이드.
사용자가 편집 도구모음을 조작할 때 HTML 코드가 동적으로 어떻게 바뀌어야 하는지를 설명하는 명세.
| 인터렉션 | 작용 전 | 작용 후 | 설명 |
|---|---|---|---|
| 기본 | 아무런 조작을 하지 않은 상태. | ||
| HTML 편집모드 | <div class="tool"> | <div class="tool off"> | 도구 버튼들은 반투명 상태가 되고 제어가 불가능 하게 된다. |
| <select> | <select disabled="disabled"> | 글꼴, 크기, 줄간격 콘트롤은 disabled 상태로 전환 된다. | |
| <div class="input_area"> <iframe style="display:block;"> <textarea style="display:none;"> </div> |
<div class="input_area"> <iframe style="display:none;"> <textarea style="display:block;"> </div> |
iframe 대신 textarea를 출력한다. | |
| 버튼 오버 | <button type="button"> | <button type="button" class="hover"> | 도구 버튼에 마우스를 올리거나(onmouseover) 키보드 포커스(onfocus)가 머무른 상태. |
| 버튼 클릭 | <button type="button"> | <button type="button" class="active"> | 도구 버튼이 클릭(onclick) 또는 키다운(onkeydown)된 상태. 또는 현재 편집중인 영역의 스타일과 버튼이 매칭될 때 관련 버튼이 활성화 된다. |
| 글자 색 | <li class="fcolor"> <div class="layer" style="display:none;"> |
<li class="fcolor"> <div class="layer" style="display:block;"> |
글자 색 팔레트를 출력한다. 이 명령은 사용자가 블럭으로 지정한 영역을 span 엘리먼트로 감싼 후 인라인으로 color 스타일을 적용하게 된다. |
| 배경 색 | <li class="bcolor"> <div class="layer" style="display:none;"> |
<li class="bcolor"> <div class="layer" style="display:block;"> |
배경 색 팔레트를 출력한다. 이 명령은 사용자가 블럭으로 지정한 영역을 span 엘리먼트로 감싼 후 인라인으로 background 스타일을 적용하게 된다. |
| 인용 | <li class="blockquote"> <div class="layer" style="display:none"> |
<li class="blockquote"> <div class="layer" style="display:block"> |
인용구 스타일 레이어를 출력한다. 이 명령은 사용자가 블럭으로 지정한 영역을 blockquote 엘리먼트로 감싼 후 blockquote 엘리먼트에 .q1~.q7 클래스를 적용하게 된다. |
| 링크 | <li class="url"> <div class="layer" style="display:none;"> |
<li class="url"> <div class="layer" style="display:block;"> |
링크 만들기 레이어를 출력한다. 이 명령은 사용자가 블럭으로 지정한 영역을 a 엘리먼트로 감싼 후 href 속성의 값을 채우게 된다. |
| 표 | <li class="table"> <div class="layer" style="display:none;"> |
<li class="table"> <div class="layer" style="display:block;"> |
표 삽입 레이어를 출력한다. 이 명령은 사용자기 지정한 영역에 table, tr, td 엘리먼트를 생성하게 된다. |
| <li class="table"> <div class="layer" style="display:block;"> |
<li class="table"> <div class="layer p1" style="display:block;"> |
표의 테두리색 레이어를 출력한다. 이 명령은 표의 배경색을 채운다. | |
| <li class="table"> <div class="layer" style="display:block;"> |
<li class="table"> <div class="layer p2" style="display:block;"> |
표의 배경색 레이어를 출력한다. 이 명령은 셀의 배경색을 채운다. | |
| 특수문자 | <li class="character"> <div class="layer" style="display:none;"> |
<li class="character"> <div class="layer" style="display:none;"> |
특수문자 삽입 레이어를 출력한다. |
| <ul class="nav"> <li><a href="#character1" onclick="return false">일반기호</a></li> |
<ul class="nav"> <li><a href="#character1" class="on" onclick="return false">일반기호</a></li> |
특수문자의 종류를 탐색할 때 선택된 메뉴 아이템을 볼드 처리한다. | |
| <ul class="list" id="character6" style="display:none"> | <ul class="list" id="character6" style="display:block"> | 특수문자의 종류를 탐색할 때 선택된 메뉴 아이템이 참조하는 특수문자 목록을 출력한다. | |
| 찾기 | <li class="find"> <div class="layer" style="display:none"> |
<li class="find"> <div class="layer find" style="display:block"> |
찾기/바꾸기 레이어를 출력한 뒤 찾기 탭과 찾기 인풋을 활성화 하게 된다. |
| 바꾸기 | <li class="find"> <div class="layer" style="display:none"> |
<li class="find"> <div class="layer replace" style="display:block"> |
찾기/바꾸기 레이어를 출력한 뒤 바꾸기 탭과 바꾸기 인풋을 활성화 하게 된다. |
- 레이어 display : block | none 제어에 인라인 스타일 시트를 사용한 이유.
- 국산 화면낭독기가 인라인 선언된 display 속성만을 제대로 처리하기 때문에 숨은 레이어 콘텐츠를 그냥 건너 뛸 수 있도록 고려함. 한편 Javascript가 동적으로 이 스타일을 변경할 때 화면낭독기 ‘센스리더’가 이것을 캐치하지 못하고 display:block 상태로 전환이 된 이후에도 그냥 건너 뛰는 문제가 발생. 센스리더 측에서 이 문제를 해결할 수 있는지 확인 및 건의가 필요함. 이 문제는 동일한 다른 상황에서도 마찬가지로 발생하는 문제.
편집 도구 버튼 활성화 규칙.
사용자가 리치 에디터를 사용하고 있을 때 커서가 놓인 지점 또는 블럭으로 선택한 지점에 어떤 스타일이 적용되어 있는지 시각적으로 분명하게 표시하기 위하여 해당 버튼을 활성화 시키는 기능.
| 규칙 | 편집 도구 버튼이 .active 클래스를 갖는 조건 | |
|---|---|---|
| 버튼 클릭 | button 엘리먼트에 onclick 이벤트가 발생 했을 때 | |
| 버튼 키다운 | button 엘리먼트에 onkeydown 이벤트가 발생 했을 때 | |
| 내용 편집 | 굵은 글꼴 | 사용자 커서가 <strong> 엘리먼트 안쪽에 머물 때 |
| 밑줄 | 사용자 커서가 <u> 엘리먼트 안쪽에 머물 때 | |
| 기울임 글꼴 | 사용자 커서가 <em> 엘리먼트 안쪽에 머물 때 | |
| 취소선 | 사용자 커서가 <del> 엘리먼트 안쪽에 머물 때 | |
| 글자 색 | 사용자 커서가 {color} 속성이 적용된 엘리먼트 안쪽에 머물 때 | |
| 배경 색 | 사용자 커서가 {background} 속성이 적용된 엘리먼트 안쪽에 머물 때 | |
| 위 첨자 | 사용자 커서가 <sup> 엘리먼트 안쪽에 머물 때 | |
| 아래 첨자 | 사용자 커서가 <sub> 엘리먼트 안쪽에 머물 때 | |
| 왼쪽 정렬 | 사용자 커서가 {text-align:left} 속성이 적용된 엘리먼트 안쪽에 머물 때 | |
| 가운데 정렬 | 사용자 커서가 {text-align:center} 속성이 적용된 엘리먼트 안쪽에 머물 때 | |
| 우측 정렬 | 사용자 커서가 {text-align:right} 속성이 적용된 엘리먼트 안쪽에 머물 때 | |
| 양쪽 정렬 | 사용자 커서가 {text-align:justify} 속성이 적용된 엘리먼트 안쪽에 머물 때 | |
| 순차 목록 | 사용자 커서가 <ol> 엘리먼트 안쪽에 머물 때 | |
| 비순차 목록 | 사용자 커서가 <ul> 엘리먼트 안쪽에 머물 때 | |
참조
- Genii Software WebEditors - 전 세계 웹 에디터 목록.
오류 정정
- 최초 글 작성시 네이버 스마트에디터에서 사용하는 프레임웍과 스마트에디터 베이직 버전에서 사용하고 있는 Javascript Framework이 동일하다고 기술하였으나 사실 확인 결과 네이버 스마트에디터는 Jindo classic(혹은 Jindo1)으로써 현재 오픈 소스로 된 Jindo와는 다른 프레임웍 입니다. 그리고 네이버 스마트에디터에 사용된 Javascript Framework은 오픈소스가 아닙니다. 관련 내용을 모두 수정하였습니다.