Micrsodft Edgeで表示されているページをHTMLで保存するブックマークレット

# 目的
保存した日時をファイル名に入れる
改行コードをcrlfに変換する
# ブックマークレットと「名前をつけて保存」の違い

|項目|ブックマークレット| 名前をつけて保存(html/単一のページ)|
|:----|:----|:----|
|文字コード|UTF-8|UTF-8|
|改行コード|LF|LF|
|ページの構成|不正確|正確|

例えば次のYahooのニュースページ
https://news.yahoo.co.jp/articles/dd13b8c3585149ceed02f56023b0aeb890deb726
を取得し、ブラウザで表示させると、次のように異なる。最も写真はブラウザが上記のURLから取ってきているので、写真自体は消える可能性がある。

### 名前をつけて保存

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/0398ba2c-a4ac-d11f-bf98-5cd620d69abd.png)

### ブックマークレット

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/62cfd0e7-a902-c1c1-ff6a-f1b09ec9cbe6.png)

### 相違
ジャンルが横ではなく縦に並ぶ
右側のトピックスの欄が消える
とデザインが変わってしまい、表示内容も異なる。
ファイルの中身も名前を付けて保存では
`<!DOCTYPE html><!DOCTYPE html><html lang="ja"><head>`
に対して
`<html lang="ja"><head>`
から始まっている。このためhtmlファイルの内容が異なる。

# ブックマークレットの目的
このような欠点があるが、一応以下のようなオーダーがあるため作成する。
## 改行コードをCrLFにする
改行コードがLFだといろいろと不都合が多いのでCRLFに変換する
## ファイル名に保存日時を入れる
ファイル名に保存日時を入れることで同じページでも繰り返し保存できる。
## 注意点
このコードもいろいろな学びがある
### 日時の取得方法
javascriptはこのような方法になるらしい。
`  var hours = ('0' + now.getHours()).slice(-2);`
[Javascript change getHours to 2 digit - Stack Overflow](https://stackoverflow.com/questions/18889548/javascript-change-gethours-to-2-digit)

### replaceのグローバル
まず`'\r\n'`は文字列リテラルだけなのでシングルクォーテーションで囲む必要がある。
次に`/***/g`はグローバルオプション（フラグ）になる
[Why do i need to add /g when using string replace in Javascript? - Stack Overflow](https://stackoverflow.com/questions/1206911/why-do-i-need-to-add-g-when-using-string-replace-in-javascript)
デフォルトは最初で一致
ここでグローバルにするものは`/***/g`と囲まなければいけない
次にこれは正規表現リテラルになるのでシングルクォーテーションで囲む必要がない。
（ちなみに囲んでも動くことは動いた）
よって中身が文字列リテラルでもシングルクォーテーションで囲む必要がない。
https://qiita.com/iLLviA/items/b6bf680cd2408edd050f
こんな簡単なことでも面倒なことになるのには少々驚きである。反面、1行単位で指定できるということでもある。

### 日時のサブストリング２桁取得
[Javascript change getHours to 2 digit - Stack Overflow](https://stackoverflow.com/questions/18889548/javascript-change-gethours-to-2-digit)
0を足して後ろから２文字取得
0<font color = Red><b>09</b></font>
0<font color = Red><b>54</b></font>
とこのようにすることで0埋めする。
PowershellやVBAでは見たことがない手法ではある。

### ブックマークレットの注釈(コメント) は後置
　今回作ってみた個人的な感想であるが、ブックマークレットの中では、`//`や`/*...*/`といったコメントは使えないことが多いようだ。
 最も、ブックマークレットの中のコード自体が目に見えないことがほとんどなので、基本的にコメントを書く必要はないとも考えられる。ただ、どうしてもコメントを挿入したい場合は、コードの最後に後置することで、問題が起こりにくくなるようだ。
　これは、ブックマークレットでは改行が消えてしまい、その後のすべてのコードがコメントと解釈されているのかもしれない。
　ブックマークレットに関する次の記事でも`//`の使用は推奨されていないとされているが、`/**/`形式のブロックコメントも、ブックマークレット内では正しく動作しない可能性があると思われる。
[ブックマークレットで始める業務改善⑩ JavaScriptで要素を絞り込もう｜シド・ブックマーカー](https://note.com/bookmarklet/n/nd528d58657d5)

### 最後にクリック
そのまま保存されるわけではなく、ダイアログが出てくるので、名前をつけて保存をクリックする。
基本の保存先は`%USERPROFILE%\Downloads\`となる。
### 保存先の指定はブラウザの設定に依存
保存先を指定するかどうかはedgeの設定の方で決定される。デフォルトのダウンロードフォルダは環境変数を用いるとこうなる。`%USERPROFILE%\Downloads\`



# ブックマークレットのコード
```javascript
javascript:(function() {
    var doc = document.documentElement.outerHTML;
    doc = doc.replace(/\n/g, '\r\n');
    var blob = new Blob([doc], {type: 'text/html'});
    var a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    var now = new Date();
    var year = now.getFullYear();
    var month = ('0' + (now.getMonth() + 1)).slice(-2);
    var day = ('0' + now.getDate()).slice(-2);
    var hours = ('0' + now.getHours()).slice(-2);
    var minutes = ('0' + now.getMinutes()).slice(-2);
    var seconds = ('0' + now.getSeconds()).slice(-2);
   a.download = document.title + ' - ' + year + month + day + hours + minutes + seconds + '.html';
    a.click();
})();
//Microsoft Edgeで表示しているページをHtmlで保存するブックマークレットただし、保存先をこのブックマークレットで指定することはできない
```