// via http://github.com/hatena/hatena-bookmark-xul/blob/master/chrome/content/common/05-HTMLDocumentCreator.js function createDocumentFromString(source){ var doc; try { doc = document.cloneNode(false); doc.appendChild(doc.importNode(document.documentElement, false)); } catch(e) { doc = document.implementation.createHTMLDocument ? document.implementation.createHTMLDocument('hogehoge') : document.implementation.createDocument(null, 'html', null); } var range = document.createRange(); range.selectNodeContents(document.documentElement); var fragment = range.createContextualFragment(source); var headChildNames = {title: true, meta: true, link: true, script: true, style: true, /*object: true,*/ base: true/*, isindex: true,*/}; var child, head = doc.getElementsByTagName('head')[0] || doc.createElement('head'), body = doc.getElementsByTagName('body')[0] || doc.createElement('body'); while ((child = fragment.firstChild)) { if ( (child.nodeType === doc.ELEMENT_NODE && !(child.nodeName.toLowerCase() in headChildNames)) || (child.nodeType === doc.TEXT_NODE &&/\S/.test(child.nodeValue)) ) break; head.appendChild(child); } body.appendChild(fragment); doc.documentElement.appendChild(head); doc.documentElement.appendChild(body); return doc; }