-
- 1. 글 작성 상태에서 취소할 때 확인 메시지 띄우기
-
-
- 1.1. 사용법
-
- 1.2. 부작용 또는 주의사항
-
- 1.3. wikiscript.js 수정
-
- 1.4. wiki.pl 수정
-
- 1.5. translations/korean.pl 수정
-
- 1.6. 호환성문제(4) 정리
-
- 1.7. 추가 업데이트 내역
-
- 1.8. 사용자 의견
-
1. 글 작성 상태에서 취소할 때 확인 메시지 띄우기
페이지를 편집하다가 실수로 "뒤로" 버튼을 누르거나 다른 링크를 클릭하거나 새로고침을 하거나 창을 닫아 버리는 바람에 글을 날려먹는 불상사를 조금이라도 피해보고자 함. 애초에 FireFox에서는 그런 경우라도 다시 "앞으로"를 하면 자기가 편집하던 내용이 살아 있는데, IE는 안 그런다. 그리고 FF에서도 주소 표시줄에서 엔터를 쳐서 새로 고침을 해 버리면 내용이 날아간다.
이글루스에 추가된 기능을 참고하였음.
- 필수 요구 사항: 브라우저들이 자바스크립트를 잘 지원해야 하겠음. IE6.0과 FireFox1.5에서 동작 확인됨.
- 선택 요구 사항: 없음
위에서 언급한 상황이 되면 아래와 같은 창이 뜬다는 얘기.
- 페이지 편집 상태에서, 텍스트 영역의 내용을 수정했을 때만 경고창이 뜬다. 즉 내용을 고치지 않은 상태에서는 뜨지 않는다.
- 편집 충돌(conflict)이 일어난 경우는 이미 자기가 작성한 내용을 날려 버릴 위기에 처한 경우이다. 이 때는 무조건 경고창이 뜬다.
반대로 자기가 일부러 뒤로 가기를 했는데 저 창이 떠서 귀찮을 때도 있겠지만, 그런 귀찮음은 감수하도록 하자.
1.2. 부작용 또는 주의사항
사용상의 부작용은 딱히 없을 듯.
주인장이 자바스크립트를 잘 몰라서, 올바르게 사용한 것인지 확실치 않음. 잘 아는 분들이 아래 구현의 내용을 봐주었으면 함.
IE와 FF에서 자바스크립트를 처리하는 방식이 다른지, 구현에 문제가 좀 있었다. 다른 브라우저를 지원하기 위해서 별도의 수정이 필요할 지 모른다. 아래에 자세히 설명. (호환성문제(1))
[WebMa]에서 탭을 닫을 때는 동작을 안 한다. 웹마 쓰는 사람들 주의.
1.3. wikiscript.js 수정
다음 함수를 추가해 준다. chk_close()는 페이지가 unload 될 때에 (닫히거나 뒤로 가거나 등) 불리게 된다. closeok 변수가 false일 때는 경고창을 띄우게 된다.
var previous_text = "", current_text = "", conflict = false, closeok = false;
function chk_close(e, str) {
if (!e) e = event;
if (!closeok) {
current_text = document.form_edit.text.value;
if (conflict || (previous_text != current_text)) {
e.returnValue = str;
}
}
}
1.4. wiki.pl 수정
페이지 편집 모드(action=edit)거나 충돌이 발생했을 때 body에다가 "on before unload" 이벤트를 잡아내어 chk_close()함수를 부르도록 한다.
sub GetHtmlHeader {
...
}
}
if (
(&GetParam("oldtime", "") ne "") ||
((lc(&GetParam("action","")) eq "edit") && (&UserCanEdit($id,1)))
) {
my $close_string = T('If you leave current page, the contents you are writing will not be stored.');
$bodyExtra .= qq( onbeforeunload="chk_close(event, '$close_string')" );
}
### 단축키
my $headExtra;
if ($UseShortcut) {
...
}
편집 폼에다가 submit시에는 경고창을 띄우지 않도록 closeok 변수를 true로 세팅하게 한다. 또한 편집 모드에 들어간 직후에 텍스트 에리어에 있는 내용을 미리 저장해둔다.
sub DoEdit {
...
print $q->startform(-method=>"POST", -action=>"$ScriptName", -enctype=>"application/x-www-form-urlencoded",
-name=>"form_edit", -onSubmit=>"closeok=true; return true;");
...
print "\n<script language=\"JavaScript\" type=\"text/javascript\">\n"
. "<!--\n"
. "previous_text = document.form_edit.text.value;\n"
. (($isConflict)?"conflict = true;\n":"")
. "document.form_edit.text.focus();\n"
. "//-->\n"
. "</script>\n";
...
}
그런데 편집 모드에서 상단의 "편집 도움말" 링크를 클릭했을 경우에도 경고창이 뜨는 문제가 있다. 그냥 새창으로 뜨는 링크는 문제가 없는 것 같은데, 편집 도움말의 경우는 자바스크립트를 사용해서 창을 만들어 띄우는 거라서 그런 듯 하다. 이걸 해결하기 위해서 도움말 관련 소스를 수정하여, 도움말 링크를 클릭했을 때도 closeok를 true로 세팅한다. (호환성문제(2): FF에서는 이 수정을 안 해도 도움말 띄울 때 경고창이 안 떴다)
sub HelpLink {
my ($id, $text) = @_;
my $url = "$ScriptName?action=help&index=$id";
return "<a onclick=\"closeok=true;\" href=\"javascript:help('$url')\">$text</a>";
}
그런데 위처럼 수정을 하니, 이번엔 반대로 한 번 이상 도움말을 클릭한 이후에는 본문 편집 창에서도 경고 기능이 동작하지 않게 된다. -_-;;; 이걸 해결을 하기 위해서는 closeok를 다시 false로 되돌려 주어야 한다.
처음 시도한 방법은 위의 wikiscript.js에서 chk_close()의 제일 마지막 부분에 close = false; 를 넣는 것이었다. 그런데 이 방법은 IE에서만 통하고 FF에서는 통하지 않았다. (호환성문제(3)) -_-;;;;
다른 방법을 찾았는데, 도움말 창을 띄우는 help()를 찾아서 close=false;를 추가한다.
function help(s)
{
var w = window.open(s, "Help", "width=500,height=400, resizable=1, scrollbars=1");
closeok = false;
w.focus();
}
여담으로, 도움말 링크에 onclick 이벤트를 넣지 않고, help(s)의 시작 부분에 closeok = true; 를 하여 경고창이 뜨지 않게 하는 방법을 써봤는데, unload 체크가 먼저 이뤄지는지 효과가 없었다.
1.5. translations/korean.pl 수정
아래 메시지 추가
If you leave current page, the contents you are writing will not be stored.
이 페이지를 벗어나면 작성중이던 글이 지워집니다.
정리를 해보면,
- 편집 도움말을 클릭하면 자바스크립트를 사용하여 새 창을 띄우게 되는데, IE는 이것도 편집하던 창이 unload된다는 것으로 인식하여 chk_close()를 호출한다. FF는 안 그런다.
- IE의 문제를 해결하기 위하여, 편집 도움말 링크에다가 onclick 이벤트를 추가하여 closeok변수를 true로 고쳐주었다.
- 그랬더니만 이번에는, IE와 FF 둘 다, 편집 도움말 창을 띄운 후에는 본문 창에서도 경고 기능이 동작을 하지 않게 된다. 따라서 편집 도움말 창이 뜬 후에 다시 closeok를 false로 바꿔 주어야 한다.
- chk_close() 함수 마지막에서 closeok를 되돌리는 방법은 IE에서만 통하고 FF에서는 안 되었다.
- 편집 도움말 창을 띄우는 help() 함수에서 closeok를 되돌린다. 이건 둘 다 통한다.
이런 식이라면 또 다른 브라우저를 위해서는 새로운 곳을 수정해야 할 지도 모른다. 알려주면 반영하겠음.
1.7. 추가 업데이트 내역
ext1.96a - 편집 상태에서 텍스트가 변경된 경우에만 경고창을 띄우도록 수정
textarea에서 onchage가 일어났는지 검사해서 일어났을 때만 메시지박스를 띄우는건 어떨까요? 그러면 뭔가 고쳤을 때만 물어볼 것 같은데에에...
- gmail의 경우는 메시지 박스 뜨기 전에 딜레이가 있는 것으로 봐서 그 정도가 아니라 진짜 서버에서 들고 있던 기본 내용이랑 바뀌었는지까지 검사하는게 아닌가 싶기도 합니다만...
음. 아예 원본 스트링을 변수에 들고 있고, 비교한 다음에 틀릴 때만 메시지 박스를 띄운다거나?
그 생각도 했는데 (태터 최근 버전은 그러더군요), 그런데 이런 비교를 wiki.pl이 할 수 있는 게 아니라 자바 스크립트에서 처리해야 되는 거잖아요? chk_close()가 불리는 시점에 그런 스트링을 어떻게 넣을 수 있는지 알 수가 없어서요. 에디트 화면에 들어가는 순간 텍스트 박스의 내용을 자바스크립트 변수에 넣어 두고, chk_close() 내에서 다시 텍스트 박스의 내용을 읽어서 둘을 비교하여 달라진 게 있는지 검사한다...라는 건데 어떻게 해야 될지;;;
텍스트를 얻어내는 것은 preview 창 띄우는 부분을 참고했고, 비교는 그냥 != 를 써도 잘 되는군요. 수정한 거 올리겠습니다.
커헉, 첫 의견글에 "onchange"를 얼핏 봤을 때 그냥 변경이 일어났는지라는 의미로 생각했는데, 지금 확인하니 onChange 라는 이벤트가 따로 있군요. -.-;
onChange보다 텍스트 얻어내서 비교하는게 확실하니 결국 더 좋은 방법으로 구현하셨네요. :-)
네, onChange에서 또다른 변수 하나를 토글시키게 해 봤는데, 이건 사용자가 다른 곳을 클릭하거나 Tab을 눌러서 포커스를 이동해야 감지가 되더군요. 그냥 텍스트 고치다가 바로 뒤로 가면 안 되더라고요.
위키위키분류