[첫화면으로]UseModWiki소스수정/작성취소시확인

마지막으로 [b]

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에서도 주소 표시줄에서 엔터를 쳐서 새로 고침을 해 버리면 내용이 날아간다.

이글루스에 추가된 기능을 참고하였음.

1.1. 사용법

위에서 언급한 상황이 되면 아래와 같은 창이 뜬다는 얘기.

Upload:cancle_alert.png

반대로 자기가 일부러 뒤로 가기를 했는데 저 창이 떠서 귀찮을 때도 있겠지만, 그런 귀찮음은 감수하도록 하자.

1.2. 부작용 또는 주의사항

사용상의 부작용은 딱히 없을 듯.

주인장이 자바스크립트를 잘 몰라서, 올바르게 사용한 것인지 확실치 않음. 잘 아는 분들이 아래 구현의 내용을 봐주었으면 함.

IE와 FF에서 자바스크립트를 처리하는 방식이 다른지, 구현에 문제가 좀 있었다. 다른 브라우저를 지원하기 위해서 별도의 수정이 필요할 지 모른다. 아래에 자세히 설명. (호환성문제(1))

[WebMa]에서 탭을 닫을 때는 동작을 안 한다. 웹마 쓰는 사람들 주의2.

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 &GetFormStart();
#   print &GetFormStart("form_edit");                              # 이 줄을 다시 아래와 같이 바꾼다
    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 href=\"javascript:help('$url')\">$text</a>";
    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.
이 페이지를 벗어나면 작성중이던 글이 지워집니다.

1.6. 호환성문제(4) 정리

정리를 해보면,

이런 식이라면 또 다른 브라우저를 위해서는 새로운 곳을 수정해야 할 지도 모른다. 알려주면 반영하겠음.

1.7. 추가 업데이트 내역

ext1.96a - 편집 상태에서 텍스트가 변경된 경우에만 경고창을 띄우도록 수정
-- Raymundo 2006-5-24 10:14 pm

1.8. 사용자 의견

textarea에서 onchage가 일어났는지 검사해서 일어났을 때만 메시지박스를 띄우는건 어떨까요? 그러면 뭔가 고쳤을 때만 물어볼 것 같은데에에...
-- 조프 2006-5-24 2:50 pm

gmail의 경우는 메시지 박스 뜨기 전에 딜레이가 있는 것으로 봐서 그 정도가 아니라 진짜 서버에서 들고 있던 기본 내용이랑 바뀌었는지까지 검사하는게 아닌가 싶기도 합니다만...

음. 아예 원본 스트링을 변수에 들고 있고, 비교한 다음에 틀릴 때만 메시지 박스를 띄운다거나?
-- 조프 2006-5-24 2:52 pm

그 생각도 했는데 (태터 최근 버전은 그러더군요), 그런데 이런 비교를 wiki.pl이 할 수 있는 게 아니라 자바 스크립트에서 처리해야 되는 거잖아요? chk_close()가 불리는 시점에 그런 스트링을 어떻게 넣을 수 있는지 알 수가 없어서요. 에디트 화면에 들어가는 순간 텍스트 박스의 내용을 자바스크립트 변수에 넣어 두고, chk_close() 내에서 다시 텍스트 박스의 내용을 읽어서 둘을 비교하여 달라진 게 있는지 검사한다...라는 건데 어떻게 해야 될지;;;
-- Raymundo 2006-5-24 3:13 pm

텍스트를 얻어내는 것은 preview 창 띄우는 부분을 참고했고, 비교는 그냥 != 를 써도 잘 되는군요. 수정한 거 올리겠습니다.
-- Raymundo 2006-5-24 5:43 pm

커헉, 첫 의견글에 "onchange"를 얼핏 봤을 때 그냥 변경이 일어났는지라는 의미로 생각했는데, 지금 확인하니 onChange 라는 이벤트가 따로 있군요. -.-;
-- Raymundo 2006-5-24 5:48 pm

onChange보다 텍스트 얻어내서 비교하는게 확실하니 결국 더 좋은 방법으로 구현하셨네요. :-)
-- 조프 2006-5-24 5:54 pm

네, onChange에서 또다른 변수 하나를 토글시키게 해 봤는데, 이건 사용자가 다른 곳을 클릭하거나 Tab을 눌러서 포커스를 이동해야 감지가 되더군요. 그냥 텍스트 고치다가 바로 뒤로 가면 안 되더라고요.
-- Raymundo 2006-5-24 6:04 pm
이름:  
Homepage:
내용:
 

위키위키분류
각주:
1. 이 때 당황해서 "뒤로" 버튼을 누른 후에 자기가 작성한 내용이 없어져서 더욱 당황하게 되는 경우가 있는데, 이럴 때는 "앞으로" 버튼을 누르고 만료된 페이지라고 나오더라도 새로 고침을 하여 불러내주면 다시 충돌 처리 화면으로 갑니다. 자기가 작성한 내용도 아래쪽에 남아 있습니다.
2. 주인장은 정말 자주 당하는 경우이다. 탭을 십수개 띄운 상태에서 정리한다고 쓱쓱 지우다가 편집 중인 창까지 닫아버린다 -_-;
찾아보기:
호환성문제   1, 2, 3, 4   

마지막 편집일: 2006-5-24 10:14 pm (변경사항 [d])
1257 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기