웹앱에는 대용량 데이터나 바이너리 파일을 오프라인으로 저장할 수 있는 기능이 있습니다. 심지어 MP3 파일을 캐시하는 것도 가능합니다. 이미 웹 브라우저 기술은 오프라인으로 데이터를 저장할 수 있으며, 대용량도 저장할 수 있습니다. 문제는 사용할 방법이 파편화되어 있다는 것입니다.

localStorage는 매우 단순한 데이터 저장소이지만, 속도도 느리고 대용량 바이너리 데이터를 다룰 수 없습니다. IndexedDB와 WebSQL은 비동기 식이며 빠르고 대용량도 다룰 수 있지만 API가 직관적이지 못합니다. 심지어 아직도 주요 브라우저 중에는 IndexedDBWebSQL를 둘 다 지원하지 않는 것도 있으며 가까운 시일 내에는 이런 상황이 나아질 것 같지도 않습니다.

만약 오프라인을 지원하는 웹앱을 작성해야 하고, 어디서부터 시작해야 할지 갈피를 못 잡겠다면 이 글이 유용할 것입니다. 오프라인 지원 기능은 한 번도 다뤄본 적이 없지만, 이 기능 때문에 골치 아픈 분이 읽어도 좋습니다. 모질라에서 만든 localForage는 어떤 브라우저에서도 손쉽게 데이터를 오프라인으로 저장할 수 있게 해 주는 라이브러리입니다.

저는 around라는 HTML5 포스퀘어 클라이언트를 개발하며 오프라인 저장소의 문제점들을 경험했습니다. localForage 사용법은 이 글에서 설명하겠지만, 코드를 꼼꼼히 보고 배우는 것을 좋아하는 분들에게는 소스도 공개되어 있습니다.

localForage는 매우 단순한 localStorage API를 사용하는 자바스크립트 라이브러리로서, get, set, remove, clear, length와 같은 기본적인 기능은 물론 다음과 같은 기능도 지원합니다.

  • 콜백을 사용한 비동기 API
  • IndexedDB, WebSQL, localStorage 드라이버 (가장 적절한 드라이버를 자동으로 선택)
  • Blob와 임의의 데이터 타입을 지원하여 이미지, 파일 등 저장 가능
  • ES6 Promises 지원

IndexedDBWebSQL을 포함한 덕분에 localStorage만 사용할 때보다 더 많은 데이터를 저장할 수 있으며, 이들의 비동기적 특성 덕분에 get/set 함수를 호출해도 메인 쓰레드가 느려지지 않으므로 앱이 더 빨라질 수 있습니다. promises를 지원하므로 콜백 수프(callback soup, 콜백이 너무 많아서 프로그램의 흐름을 알기 어렵게 된 상태) 없이 자바스크립트를 작성할 수 있습니다. 물론 콜백을 좋아한다면 localForage는 그 방법도 지원합니다.

얘기는 그만. 어떻게 동작하는지 보여줘!

localStorage API는 여러 경우에 있어 사실 꽤 훌륭합니다. 사용하기 편하고 복잡한 데이터 구조를 만들지 않아도 되고, 단순하여 별도의 코드 조각이나 라이브러리가 따로 필요하지 않습니다. 예를 들어, localStorage를 사용해 앱 설정을 저장하고 싶다면 다음과 같이 작성할 수 있습니다.

// 오프라인으로 저장할 설정값
var config = {
    fullName: document.getElementById('name').getAttribute('value'),
    userId: document.getElementById('id').getAttribute('value')
};
 
// 다음에 앱을 실행할 때 사용하기 위해 설정값을 저장한다.
localStorage.setItem('config', JSON.stringify(config));
 
// 다음에 앱을 실행할 때 다음과 같이 사용할 수 있다.
var config = JSON.parse(localStorage.getItem('config'));

단, localStorage에는 문자열 형식으로 값을 저장해야 하므로 값을 JSON 형태로 혹은 JSON 형태에서 변환해야 합니다.

아주 기분 좋을 정도로 직관적이지만 금세 localStorage에 있는 문제점을 깨닫게 될 것입니다.

  1. 동기식이다. 데이터가 얼마나 크던 데이터를 디스크에서 읽어 들여 해석할 때까지 기다려야 합니다. 이 때문에 앱의 반응성이 느려질 것입니다. 이는 특히 모바일 디바이스에 안 좋은데 데이터를 완전히 읽어 들일 때까지 메인 쓰레드가 대기해야 하므로 여러분의 앱은 느리고 반응성까지 떨어지는 것처럼 보일 것입니다.
  2. 문자열만 지원한다. 반드시 JSON.parseJSON.stringify를 사용해야 합니다. 이는 localStorage가 값으로 자바스크립트 문자열 형식만 지원하기 때문입니다. 숫자도, 불리언도, 대용량 바이너리 데이터 등도 저장할 수 없습니다. 이 때문에 숫자나 배열을 저장하는 작업은 귀찮아지고, 대용량 바이너리 데이터를 저장하는 것은 사실상 불가능합니다(최소한 엄.청. 짜증나고 느릴 것입니다).

localForage를 사용한 더 좋은 방법

localForage는 localStorage의 API를 사용하면서도 비동기식 API를 사용해 이 같은 문제를 극복했습니다. 다음은 같은 데이터를 저장할 때 IndexedDB와 localStorage의 사용법을 비교한 것입니다.

IndexedDB 코드

// IndexedDB.
var db;
var dbName = "dataspace";
 
var users = [ {id: 1, fullName: 'Matt'}, {id: 2, fullName: 'Bob'} ];

var request = indexedDB.open(dbName, 2);
 
request.onerror = function(event) {
    // 에러 처리
};
request.onupgradeneeded = function(event) {
    db = event.target.result;
 
    var objectStore = db.createObjectStore("users", { keyPath: "id" });
 
    objectStore.createIndex("fullName", "fullName", { unique: false });
 
    objectStore.transaction.oncomplete = function(event) {
        var userObjectStore = db.transaction("users", "readwrite").objectStore("users");
    }
};
 
// 데이터베이스가  생성되고 나면 사용자를 추가한다
 
var transaction = db.transaction(["users"], "readwrite");
 
// 데이터가 데이터베이스에 모두 저장되었을 때 할 일
transaction.oncomplete = function(event) {
    console.log("All done!");
};
 
transaction.onerror = function(event) {
    // 에러도 빠뜨리지 말고 다루어야 한다
};
 
var objectStore = transaction.objectStore("users");
 
for (var i in users) {
    var request = objectStore.add(users[i]);
    request.onsuccess = function(event) {
        // Contains our user info.
        console.log(event.target.result);
    };
}

WebSQL은 번잡하다 싶을 정도는 아니지만 그래도 기본 코드가 약간 필요하긴 합니다. localForage에서는 다음과 같이 사용하면 됩니다.

localForage Code

// 사용자를 저장한다
var users = [ {id: 1, fullName: 'Matt'}, {id: 2, fullName: 'Bob'} ];
localForage.setItem('users', users, function(result) {
    console.log(result);
});

얼마 차이 안나는군요?

문자열 외의 데이터 저장하기

사용자의 프로필 이미지를 다운받은 뒤 오프라인 상태에서 볼 수 있도록 캐시한다고 생각해 봅시다. localForage에서는 바이너리 데이터를 간단하게 저장할 수 있습니다.

// AJAX를 사용해서 사용자의 사진을 다운로드한다
var request = new XMLHttpRequest();
 
// 첫 번째 사용자의 사진 가져오기
request.open('GET', "/users/1/profile_picture.jpg", true);
request.responseType = 'arraybuffer';
 
// AJAX 상태가 변경되면 사진을 로컬에 저장한다.
request.addEventListener('readystatechange', function() {
    if (request.readyState === 4) { // readyState DONE
        //localStorage로는 바이너리 데이터를 있는 그대로 저장할 수 없었을 것이다.
        localForage.setItem('user_1_photo', request.response, function() {
            // 사진이 저장되었다. 다음 단계를 진행하자.
        });
    }
});
 
request.send();

저장한 사진을 가져올 때는 코드 3줄만 있으면 된다.

localForage.getItem('user_1_photo', function(photo) {
    // data URI 등을  만들어 img 태그 등에 사진을 표현한다
    console.log(photo);
});

Callback과 Promise

코드에서 콜백을 사용하고 싶지 않다면, localForage에서 콜백 함수를 인수로 사용하는 대신 ES6 Promise를 사용할 수 있습니다.

localForage.getItem('user_1_photo').then(function(photo) {
    // data URI 등을  만들어 img 태그 등에 사진을 표현한다
    console.log(photo);
});

사실 이 예제는 조금 억지로 만든 감이 있습니다. 그러나 around를 살펴보면 이 라이브러리가 실제로 사용되는 것을 볼 수 있습니다.

크로스 브라우저 지원

localForage는 최근 브라우저를 모두 지원합니다. IndexedDB사파리 외의 모든 최근 브라우저에서 지원하고 (IE 10+, IE Mobile 10+, Firefox 10+, Firefox for Android 25+, Chrome 23+, Chrome for Android 32+, and Opera 15+), 내장 안드로이드 브라우저(2.1+)와 사파리는 WebSQL을 사용합니다.

가장 안 좋은 경우라 해도 localForage는 localStorage를 대비책으로 사용하므로 최소한 기본적인 데이터는 오프라인으로 저장할 수 있게 됩니다(하지만 이 경우 Blob은 저장할 수 없고 많이 느릴 수도 있다). 그러나 적어도 자동으로 데이터를 JSON 문자열로 변환 혹은 JSON 문자열을 데이터로 변환해주는 정도의 이점은 얻을 수 있습니다.

localForage에 대한 자세한 정보는 Github에서 볼 수 있으며 localForage가 해줬으면 하는 기능이 있다면 이슈에 추가해주세요.

이 글은 localForage: Offline Stroage, Improved를 번역한 글입니다. 원문의 라이센스에 따라 CC BY-SA로 공개합니다.


Posted by 행복한고니 트랙백 0 : 댓글 0
지난 22일에 파이어폭스의 새 버전이 나왔습니다. 여전히 버전은 3.6 대이지만, 3.7 에서 도입하려고 했던 플러그인 오류 보호 시스템이 포함되었습니다(크롬 브라우저의 그것과 유사합니다).

오류 보호 기능은 플러그인을 자신만의 프로세스로 분리합니다. 즉, 플러그인이 비정상적으로 종료되거나 멈추더라도 브라우저 전체에 영향을 미치지는 않게 됩니다. 모질라 의하면 브라우저가 죽는 원인의 1/3 이 써드파티 플러그인 때문입니다.

현재는 리눅스와 윈도우즈 버전에만 오류 보호 기능이 포함되어있으며, 맥 사용자들은 올해 말쯤에 출시될 파이어폭스 4까지 기다리셔야 합니다. 버전은 아주 조금 바뀌었는데, 정말 좋은 기능이 포함되었습니다.

from Firefox joins Chrome in plugin crash protection
Posted by 행복한고니 트랙백 2 : 댓글 1

CSS calc()

2010.06.16 08:40 from [IT] Web Tech

CSS에서 상대적인 크기 계산을 위해 자바스크립트를 사용해본 기억이 있을 것입니다. 예를 들어, '절반(50%)에서 5px 뺀 너비' 등과 같이 말이죠. 하지만, 이젠 그럴 필요가 없게 됐습니다.

Paul Roget씨가 CSS calc()에 대해서 설명해주셨습니다. CSS calc()는 아직 버그가 있는 상태입니다.

다음은 간단한 사용예입니다.
[code:css]
/*
* Two divs aligned, split up by a 1em margin
*/
#a {
  width:75%;
  margin-right: 1em;
}
#b {
  width: -moz-calc(25% - 1em);
}
/*
 * Make sure input field won't overlap parent
 */
input {
  padding:2px;
  border:1px solid black;
  display:block;
  width: -moz-calc(100% - 2 * 3px);
}

/*
 * combine different units!
 */

width: -moz-calc(3px + 50%/3 - 3em + 1rem);
이 덕분에 상당히 많은 자바스크립트를 줄일 수 있게 되었습니다. 하지만, Firefox에서만 가능한 방법이라 실무에 적용하기는 다소 어려울 듯 합니다. ^^;

from CSS calc() in the house
Posted by 행복한고니 트랙백 1 : 댓글 2
Firefox 3.1가 HTML5의 <video>와 <audio>태그를 지원합니다. 마음에 쏙드는 이 멋진 글Mozilla 개발자 포털에 막 올라온 정보입니다. Firefox 3.1은 현재 Ogg 포맷을 지원하고 있지만, 다른 포맷들에 대한 지원도 검토중이라고 합니다.

문서에 있는 사용 예제입니다.
[code:html]
<video src="http://v2v.cc/~j/theora_testsuite/320x240.ogg" autoplay>
Your browser does not support the <code>video</code> element.
</video>
참 쉽죠? 다른 형식의 여러 원본을 정할 수도 있습니다.
[code:html]
<video autoplay>
  <source src="foo.ogg" type="video/ogg"></source>
  <source src="foo.mov"></source>
  Your browser does not support the <code>video</code> element.
</video>
주의할 것은 아직 source 엘리먼트가 완전히 지원되는 것은 아니라는 점입니다.

미디어 재생은 자바스크립트로 컨트롤 될 수 있습니다.
[code:js]
var v = document.getElementsByTagName("video")[0];
v.play();
사용할 수 있는 이벤트가 상당히 많아서(22개나 있습니다!), 서로 다른 미디어 이벤트에 기반해서 어떤 동작을 붙이거나 UI를 업데이트 할 수 있습니다.
[code:js]
var v = document.getElementsByTagName("video")[0];

v.addEventListener("seeked", function() { document.getElementsByTagName("video")[0].play(); }, true);
v.currentTime = 10.0;
이 코드는 탐색이 일어나면 작동합니다.

from Firefox 3.1 to support HTML 5 video and audio
Posted by 행복한고니 트랙백 0 : 댓글 0
Mark Finkle씨가 Mozilla의 모바일 웹 브라우저인 Fennec의 첫 알파 버전을 릴리스했습니다. 최근 Window Mobile 버전의 진행에 대한 논의가 있긴 했지만, 이번 버전은 Nokia N800과 N810에서만 작동합니다.

하지만, Mozilla는 Fennec을 데스크톱에서 실행해보고 싶은 사람들을 위해서 에뮬레이터도 제공하고 있습니다. 그리고 브라우저 UI뿐만 아니라 그 외 여러면에서 피드백을 달라고 부탁하고 있습니다.
Fennec (Mobile Firefox)는 첫번째 알파인 마일스톤 9까지 진행되었습니다!  우리는 이번 판을 사용자 경험 알파라고 부르고 있습니다.

이전 마일스톤처럼, M9는 Nokia N800/N810 (Maemo) 인터넷 타블렛을 대상으로 했습니다. 네, Window Mobile 플랫폼에서 상당한 진전이 있었지만, 아직 릴리스할 단계는 아닙니다. 하지만, 네이티브 Maemo 릴리스와 함께, 우리는 Fennec의 데스크톱 버전도 릴리스했습니다. 그렇습니다. 여러분은 Fennec을 Windows, OS X 혹은 리눅스 데스크탑에도 설치해볼 수 있습니다! 저희는 여러분들이 디바이스가 없더라도 경험해보고, 피드백을 주고, 부가기능을 작성하며 Mozilla Mobile 프로젝트에 참여할 수 있기를 바랍니다.
실행 동영상도 있습니다.


from Fennec (Mobile Firefox) Alpha 1 Released
Posted by 행복한고니 트랙백 0 : 댓글 0
사용자 삽입 이미지

우리는 간단한 CSS를 통해 크기를 바꾸고, 변형하고, 기울이고, 매트릭스 작업을 할 수 있는 WebKit의 CSS 변형에 대해 얘기한 바 있습니다.

새로운 -moz-transform 덕분에 Mozilla는 진보했고, Keith Schwarz씨는 Firefox에서의 CSS 변형 지원에 대한 글을 작성하셨습니다.
[code:css]
-moz-transform: translate(100px, 200px); /* Move right 100 pixels, down 200 pixels */
-moz-transform: translate(30px); /* Move down and right 30 pixels */
-moz-transform: translate(50%, 50%); /* Move down and right by 50% of the size of the element. */
이 기능은 지정된 오프셋만큼 단순히 엘리먼트를 이동시킵니다. 예를 들어 -moz-transform: translate(100px)가 설정된 텍스트 엘리먼트는 원래의 위치에서 100 픽셀 우측 하단에 나타납니다. 물론, 단순한 변형 이상의 기능들도 있습니다. 예를 들면, 엘리먼트를 지정한 각도의 숫자만큼 회전시키는 회전; 엘리먼트를 각 축의 임의의 선을 기준으로 축소, 확대시키는 스케일; X, Y 축을 따라 기울이는 기울임; 그리고 임의의 매트릭스 변형을 위한 매트릭스 기능 등이 있습니다. 또한 skewx(X축 기울임), skewy(Y축 기울임)과 같이 몇가지 경우에 대해 보다 단순한 문법을 사용할 수 있는 단순한 버전도 있습니다.

CSS변형을 위해 개발자들이 사용한 것이 무엇인지를 보는 것도 재밌을 것입니다. 기능의 대부분들은 플러그인에서 구현될 예정이었지만, 지금은 CSS와 JavaScript에 직접 통합되어 웹 개발자들이 현재의 페이지들을 보다 생생하게 만드는 것에 도움을 줄 것입니다. 우리는 또한 이제 두 개의 구현체가 있게 된 이 속성의 표준화가 빨리 이루어지기를 기대하고 있습니다.

from CSS Transforms: First WebKit, now Gecko too!
Posted by 행복한고니 트랙백 2 : 댓글 0
Mozilla에겐 바쁜 한 주 였습니다. 이번에 그들의 기술을 한번 살펴볼까 합니다.

우선, 새 소식입니다. Firefox 3가 6월 17일에 공개된다고 합니다. 다운로드 관련 이벤트도 진행중이죠.

Stuart Pamenter씨가 글꼴과 텍스트에 대해 자세한 글을 작성하셨습니다.
Mozilla 개발자들이 Cairo를 통합하고 새로운 그래픽 레이어를 처음부터 작성하기로 했을 때, 그들은 브라우저에서 텍스트를 렌더링하는 시스템도 완전히 새로 작업하기로 했습니다.

텍스트는 웹에서 믿을 수 없을만큼 중요한 부분입니다. 그래픽, 오디오, 동영상의 중요성은 커가고 있지만, 우리는 여전히 Web에서의 시간 대부분을 무언가를 읽는데 사용합니다. 웹 브라우저에서 여러분이 읽는 모든 글들은 글꼴을 사용해 렌더링되며, 글꼴은 각각의 문자 형태를 만드는 데 사용하는 글리프glyph 묶음을 포함합니다. 보다 단순한 언어를 위해서 한 글자에 글리프 하나씩 1:1로 매핑합니다. 하지만 보다 복잡한 언어를 위해서는 하나의 글리프가 여러 문자들을 표현하기도 합니다.
Ben씨는 이런 종류의 것들에 엄청난 팬(anal이라 하기도 합니다)입니다. 글꼴과 렌더링은 큰 차이를 만들어냅니다. 그 글은 새로운 Firefox 3 엔진에서는 어떤 일들이 일어나는지에 대해 자세한 설명을 계속했습니다. 커닝, 활자, 힌팅, 폰트 부드럽게하기, 안티-알리아싱 등에 대해 논의했습니다. 이 글을 읽고 난 뒤에 여러분은 아마도 영화 Helvetica를 보고 싶을지도 모릅니다!

이제 모바일 쪽 얘기를 해보겠습니다. Aza Raskin씨가 Fennec을 위해 작성될 새로운 터치 스크린 인터페이스에 대한 컨셉 동영상을 포스팅했습니다. Aza씨는 설계 원칙을 포함해 상당히 많은 양의 자세한 내용을 작성했습니다.
터치 Firefox 모바일(코드네임 Fennec)을 위한 이 컨셉 프로토타입은 터치 스크린을 위해 설계되었습니다. 멀티터치는 왜 안될까요? Firefox는 터치 장치들의 최소 공통 요소에서 실행되어야 하기 때문입니다. 특히 터치가 가능한 인터페이스를 직접 조작하는 것이 중요합니다. 그 생각과 동일선상에서 인터페이스는 손가락으로 작동할 수 있어야 합니다. 입력 장치들을 왔다갔다하는 것은 시간도 들고 짜증나는 일이기 때문에, 사용자들은 스타일러스 혹은 다른 두번째 입력장치로 바꾸지 않아도 되어야 합니다. Firefox는 터치스크린이 아닌 장체이서 작동합니다, 하지만 그 부분은 이 데모의 범위가 아닙니다.

큰 타겟이 좋다 인터페이스를 컨트롤하는 똑같은 손가락 끝은 모바일 터치 스크린 수평/수직 높이/너비의 1/5 에서 1/10 까지의 크기입니다. 다시 말해, 손가락은 두껍습니다: 작은 타겟을 맞추는 것은 팔꿈치로 터치하려는 것과 마찬가지입니다. 모든 액션은 빠르고 쉽고 (최소한) 찍느라 화나는 일이 없을 만큼 충분히 큰 타겟에 의해 표현되어야 합니다.

시선을 잡아끄는 탄성과 물리의 매력 이쁜 애니메이션과 물리 엔진을 만큼 "섹시!"하게 보이는 것도 없습니다. 이런 물리력의 구현은 마케팅 차원에서 어필할 뿐만 아니라, 사용자가 인터페이스의 정신적 모형을 만드는데 도움을 주며 그런 인터페이스에 일관성을 부여합니다. 실제 세상과는 다르게 나타났다가 사라지지 않더라도, 인간은 물체들이 어떻게 움직여서 어디로 가는지를 추적하고 기억하게 되어있습니다. 물론 모든 물리적 상징들을 무턱대고 베낀다면 Microsoft Bob같이 억만금을 들인 참담한 인터페이스가 만들어질테니 상징들을 신중하게 골라야합니다.

타이핑은 어렵다 이는 어디서 무엇을 하든 키 입력을 최소화 할 필요가 있다는 것을 의미합니다.

컨텐트가 왕 제한된 화면 크기에서 모든 픽셀은 중요합니다. 가능한 많은 부분을 항상 제어기능이나 잡동사니가 아닌 컨텐트에 할당해야 합니다.
이제 서버 쪽을 얘기해보자면, Firefox 3를 포함한 Weave status update가 있습니다. 데이터 타입, 북마크 공유, 웹 클라이언트 뷰와 같은 새로운 기능들을 포함하고 있습니다. 보다 자세한 정보를 위해 위키를 확인해보세요.

from Mozilla Week: From Client (Firefox 3) to Server (Weave) to Mobile (Fennec)
Posted by 행복한고니 트랙백 0 : 댓글 0
from window.crypto: want crypto primitives in the browser? You may already have it on Ajaxian

초라한 JavaScript 개발자들을 위해서 사용할만한 crypto 헬퍼가 브라우저에 추가되면 참 좋을 것 같습니다. 그래서 예전에 요청한 적이 있었습니다.

Brad Neuberg 씨가 Gecko 에 window.crypto 라는 내장 crypto가 있음을 발견했습니다.

Mozilla는 웹페이지가 어떤 암호 관련 서비스에 접근할 수 있도록 하는 특별한 JavaScript 객체를 정의해두었습니다. 이 서비스들은 웹 페이지가 필요로 하는 기능과 악의적 웹 사이트로부터 사용자들을 보호하려는 요구 사이의 균형점입니다. 대부분의 이 서비스는 JavaScript에서 window 객체를 통해 window.crypto와 같이 사용할 수 있습니다. 예컨데, 암호 엔진을 통해 10 byte의 랜덤한 숫자를 얻으려면 이렇게 사용하면 됩니다:
var myrandom = window.crypto.random(10);

서비스에서 제공하는 것은 이렇습니다: 스마트 카드 이벤트, 인증 요청 생성, 사용자 인증 가져오기, 랜덤한 숫자 생성, 토큰과 서명 로깅
Posted by 행복한고니 트랙백 0 : 댓글 0
from Browser Update: Firefox 3b5 and Opera Mini 4.1 beta on Ajaxian

Firefox3 Beta 5  가 출시되었습니다.
Firefox2 와 비교해서 Google Mail 이나 Zoho Office 같은 웹 어플리케이션들이 Firefox 3 Beta 5에선 두배 빨라졌고, Apple의 유명한 SunSpider 테스트 결과 이전 릴리스 버전보다 개선되었습니다. PGO(profile guided optimizations) 뿐만 아니라 JavaScript 엔진의 속도가 점차 나아짐에 따라 성능이 계속 좋아지고 있습니다.
Opera도 Opera Mini 4.1 Beta 를 새롭게 출시했습니다. 속도면에서 개선이 이루어졌다고 합니다. JSR-75도 지원해서 이를 지원하는 가장 최신의 브라우저가 되었다고 합니다:
JSR-75는 Opera Mini같은 Java 응용프로그램이 전화기 내부의 저장장치나 기능으로의 접근하는 것에 대한 명세서이다. "페이지 저장", "파일 내려받기/올리기"와 같은 몇몇 Opera Mini의 기능은  기기에서 지원하는 JSR-75에 따라 달라진다.
Posted by 행복한고니 트랙백 0 : 댓글 0
원본글 : Happy 10 years Birthday Mozilla

넷스케이프에서부터 모질라 프로젝트가 시작된지 어느덧 10년이랍니다. 모질라 페이지와 모질라 한국 페이지에 갔더니 Mitchell Baker 씨가 쓴 글이 대문에 게시되어있네요(오늘이 지나면 한글 페이지는 어디서 찾아야 할까요? -_-? )
Celebrating 10 years of Mozilla
Celebrating 10 years of Mozilla

Posted by 행복한고니 트랙백 0 : 댓글 0

티스토리 툴바