WHATWG Blog에서 전한 내용: WHATWG Weekly: Now it’s <time> for <data>

HTML5에 포함되었던, 주로 시간과 날짜를 마크업 할 때 사용되던, time element가 보다 폭넓은 데이터 형식에 대한 요구를 수용하기 위해 schema.org에 정의된 Microdata 용어를 사용하는 data element로 대치되었다는 소식.

이번의 변경을 가져온 처음의 제안 내용과 논의를 살펴보면 적지 않은 반대 의견도 살펴볼 수 있는데, 개인적으로도 time element가 소개되기 이전에 미리 이러한 논의가 이뤄져서 개발자의 혼란을 막았었으면 하는 아쉬움이 있다. (HTML5는 아직 Working Draft임을 감안하더라도.)

Spec에 나와 있는 data element의 사용법을 살펴보면, data element는 감싸고 있는 내용에 대한 기계적으로 해석되는 용도의 value attribute을 항상 포함하고 있어야 한다.

간단한 예로, data element를 써서 특정 시간을 마크업 한 예.

<p>Our first date was <data value="2006-09-23">a Saturday</data>.</p>

다음은 data element로 schema.org에 정의된 Microdata 용어를 써서 블로그 글이 작성된 날짜를 마크업 한 예.

<article itemscope itemtype="http://schema.org/BlogPosting">
 <h1 itemprop="headline">Small tasks</h1>
 <footer>Published <data itemprop="datePublished" value="2009-08-30">yesterday</data>.</footer>
 <p itemprop="articleBody">I put a bike bell on his bike.</p>
</article>

data-* attributes과 마찬가지로 문서에 저장된 다양한 형식의 정보를 data element를 써서 기계와 JavaScript가 접근하기 쉽게 해놓았다지만, 마크업 하기 간단명료했던 time element의 어쩔 수 없는 퇴장은 그래도 아쉽다. 아직 덜 똑똑한 기계 때문에 이런 혼란스런 상황이 벌어졌고, 그래서 더 부지런해야만 하는 것은 개발자들의 몫으로 남겨졌다.

덧붙임: time element의 완전한 삭제/퇴장/배제를 재고해달라는 공식 요청
결국 time, data element가 공존하는 방향으로 갈 수도 있을듯한데 어떻게 될지는 지켜볼 일.

덧붙임 2: 결국, WG 회원들 간의 충분한 논의가 없었음을 인지하고 이번 사건과 관련된 spec의 수정은 일단 보류되었다.

CSS의 :visited pseudo-class가 흘릴지도 모를 사적인 방문 기록 노출에 대한 염려로 인해서 이 문제에 대한 처방으로 IE6-8과 Opera 11.52를 제외한 지금의 모든 최신 브라우저에선 :visited에 선언된 properties 중 color property만이 적용되고 나머진 그냥 무시한다.

자세한 설명은 이 문제를 먼저 제시해서 알게 된 인용 문서를 참고: Limitations on Styling Visited Links

덩달아 JavaScript에서 사용자가 방문했던 링크의 color property를 window.getComputedStyle을 써서 얻으려 할 때에도, 당연히 history sniffing 문제로 대신에 그냥 보통 :link에 선언된 color 값을 돌려준다.

결국, 이러한 상황에서 :visited pseudo-class엔 다른 것은 건들 필요없이 적당한 color 값만 지정해 줘도 충분하다는 얘기.

그런데 유독 Opera만이 최신 버전에서도 다른 브라우저와 달리 예외적인 모습을 보여주는데, Opera에서 이 문제와 관련한 history sniffing을 막으려면 Opera Community 포럼에서 논의된 내용으로 주소창에다 opera:config#VisitedLink|VisitedLinksState를 입력하고서, Visited Links State 값을 기본값인 2에서 1 혹은 0 값을 주면 된단다. (0 – disable :visited links state, 1 – match same domain only.)

JavaScript 파일은 페이지 로딩 속도 측면에서 페이지의 body가 닫히기 바로 전에 추가해 주는 것이 가장 좋은데, WordPress에 기본적으로 추가된 jQuery는 꼭대기 head 부분에 붙어 있다.

이놈을 맨 아랫부분에 추가하려면, 테마 파일에 있는 functions.php 파일을 열고 WordPress의 wp_register_script()wp_enqueue_script() function을 사용하는 다음과 같은 코드를 추가해 준다.

<?php
function my_scripts_enqueue() {
  wp_deregister_script('jquery');
  wp_register_script('jquery'"http" . ($_SERVER['SERVER_PORT'] == 443 ? "s" : "". '://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'falseNULLtrue);
  wp_enqueue_script('jquery');
}
 
if (!is_admin()) add_action('wp_enqueue_scripts''my_scripts_enqueue'11);
?> 

여기에 있는 wp_register_script() function의 parameter 중 네 번째와 다섯 번째가 중요한 요소인데, 각각 $ver$in_footer 변수를 의미한다.

$ver 변수는 보통 JavaScript 파일 경로의 마지막 부분에 query string처럼 붙으면서 JavaScript 파일이 갱신되었을 때 caching된 것의 사용을 막으려고 사용되는데, jQuery처럼 Google CDN에서 불러올 때는 오히려 방해되므로 NULL 값을 줘서 없애버린다. 그리고 $in_footer 값에 true를 주면 JavaScript가 body 맨 마지막 부분에 붙게 된다.

내용 갱신(2014년 6월 25일): 현재 설치된 WordPress 3.9.1 버전에선 위에서 설명했던 방법이 제대로 적용되질 않아서, 해결책을 검색한 결과 다음 페이지에서 해답을 얻을 수 있었다.: Unable to move wordpress jquery library into the footer – Stack Overflow

그래서, 가령 jQuery를 Google에서 호스팅하고 있는 것으로 바꿔서 페이지 마지막 부분에 추가해 주려면 functions.php 파일에 다음과 같이 등록해 준다.

<?php
function my_footer_enqueue_scripts() {
    remove_action('wp_head''wp_print_scripts');
    remove_action('wp_head''wp_print_head_scripts'9);
    remove_action('wp_head''wp_enqueue_scripts'1);
    wp_deregister_script('jquery');
    wp_register_script('jquery'"http" . ($_SERVER['SERVER_PORT'] == 443 ? "s" : "". '://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'falseNULLtrue);
    wp_enqueue_script('jquery');
}
 
if (!is_admin()) add_action('wp_enqueue_scripts''my_footer_enqueue_scripts');
?> 

나중에, Google에서 호스팅하고 있는 jQuery 버전이 갱신된다면, 위 코드에 작성된 jQuery의 호스팅 주소 중에 버전에 해당되는 부분만 새 것으로 바꿔주면 된다.

말장난으로 시작한 제목과는 달리 역설적으로 JavaScript에선 global space를 더럽히는 일은 죄악처럼 여겨진다. 특히나 통제할 수 없는 다른 사람이 작성한 JavaScript 코드가 섞여들어 갈 가능성이 큰 Client-Side JavaScript에선 더욱 그러하다.
그래서 뜻하지 않는 이런 실수를 저지르지 않으려면 변수가 global 해지는 경우를 정확하게 알고 있어야 하는데, 그 예로 다음과 같은 몇 가지 경우가 있다.

var로 시작되지 않는 변수 선언.

잘 알려진 내용으로 var 없이 선언된 변수는 global object의 properties에 붙게 된다.
참고로, 이렇게 만들어진 property는 var 선언문으로 생성된 property와는 다르게 다시 나중에 delete로 지울 수 있다.

var x = 1;      // A properly declared global variable, nondeletable. 
= 2;          // Creates a deletable property of the global object. 
this.= 3;     // This does the same thing. 
delete x;       // => false: variable not deleted 
delete y;       // => true: variable deleted 
delete this.z;  // => true: variable deleted 

다음은 JavaScript의 delete operator 작동 원리에 대한 자세히 설명해놓은 글. – Perfection Kills – Understanding delete

JavaScript에서 global 해지는 법(이)란 제목의 글 마저 읽기 →

HTML5 Boilerpate가 탄생 1주년을 맞아 2.0으로 갱신되었다.

눈에 띄게 바뀐 점이라면 모든 스타일을 기본적으로 밋밋하게 밀어버리는 CSS의 불도저라고 볼 수도 있는 일반 CSS Reset 스타일시트를 버리고 normalize.css로 갈아탄 것. 브라우저별 공통분모는 건드리지 않고 차이를 보이는 놈들만 꼭 집어서 일관성 있게 바꿔준다.
다음 링크로 가면 예전 Reset CSS 스타일을 쓴 것과 새로운 nomalize 스타일을 입힌 후 바뀐 각 element의 차이점을 확인해 볼 수 있다. – HTML5 Boilerpate CSS 변화로 각 엘르먼트의 기본 스타일 차이점

또, Build Script에는 offline 앱을 위한 appcache manifest 파일 자동 생성 기능도 새로 추가되었는데, 빌드 스크립트를 쓰지 못할 상황이라면 사이트 주소만 입력해주면 자동으로 해당 사이트의 appcache 파일을 생성해주는 Cache Manifest Validator도 유용할 것이다. 이 사이트에선 Textmate Bundle도 함께 제공하고 있음.

그리고 이미 예상된 것이지만, 이제 기본적으로 IE6 사용자에겐 Chrome Frame 설치를 권고하게 된다.

더불어 Modernizr 2 안에 respond.js도 함께 추가되면서 요즘 새로 시작되는 웹 프로젝트에는 거의 필수가 되어버린 Responsive Web Design과 ‘Mobile First’ 디자인을 적용해 볼 수 있는 기본 밑바탕도 마련되었다.