イメージプレビュー系ライブラリ
Fancybox3
https://fancyapps.com/fancybox/3/
jQuery
良い感じだけど jQuery 依存なのだけがネック
モバイル対応や GPU アクセラレーションやマルチインスタンス対応など高機能なのでもったいない

Fullscreen Lightbox
https://fslightbox.com/javascript
VanillaJS
jQuery 依存ないし良い感じだけど無料版は基本機能だけ
ズーム・サムネ・キャプション・ツールバー など便利機能は有料版の PRO 必要

Lightbox2
https://lokeshdhakar.com/projects/lightbox2/
jQuery
これがこの系統ライブラリのスタンダード?
lightbox 系と呼ばれたりもするし元になったらライブラリぽい
jQuery 必要だし機能もシンプルで最低限だけみたいなので あえて選択はしなくていいかも

WA MediaBox
https://jiri.hybek.cz/wa-mediabox/
VanillaJS
ドキュメントみても情報少なめ(機能が自体が少なめ?)
DEMO の感じだと ZOOM とかキャプションなど高機能なものはなさそう
画像ロード遅め(DEMO の画像が重いだけかも)

PhotoSwipe
https://photoswipe.com/
VanillaJS
ツールバーやキャプションにズームなど 基本機能以上の機能があるしモバイルも対応
さらに VanillaJS ととても良さそうなのに特に聞かない名前だし ウェブサイトもシンプルでちょっと古めなイメージの見た目

lightgallery.js
https://sachinchoolur.github.io/lightgallery.js/
VanillaJS
VanillaJS ですごく高機能
ツールバーやキャプション・ズームに加えて サムネ表示やサムネにカーソル合わせたときのアニメーションもある
ウェブサイトもきれいでアニメーションやロード画面などあって PhotoSwipe よりできる感ある
久々に古い JavaScript で非同期処理を書いた
async/await ないのけっこうつらい

async function main(){
let x = 100
console.log(1)
x += 200
await new Promise(r => setTimeout(r, 1000))
console.log(2)
x += 300
await new Promise(r => setTimeout(r, 2000))
console.log(x)
}
main()
// 1
// 2
// 600

これをするのがこうなる

function main(){
var x = 100
seq([
function(n){
console.log(1)
x += 200
setTimeout(n, 1000)
},
function(n){
console.log(2)
x += 300
setTimeout(n, 2000)
},
function(n){
console.log(x)
n()
}
])
}

function seq(a){
var i = 0
function next(end){
if(end) return
var fn = a[i++]
var args = Array.prototype.slice.call(arguments)
args[0] = next
if(fn) fn.apply(null, args)
}
next()
}

main()
// 1
// 2
// 600

非同期処理用の関数を順番に実行する seq 関数を事前に準備しておく
await したい非同期処理の場所でコードを分割してそれぞれを関数にする
その関数の配列を seq に渡して実行

seq から実行される関数には引数で次の実行のための関数と前の処理から渡された値を受け取る
非同期処理のコールバック関数として 引数で受け取った次の処理を行うための関数を設定すれば await 代わりになる
途中で return したいこともあるので引数で渡される関数の第一引数に true を渡せば途中も終了できる

ローカル変数は引き継がないので seq を実行するスコープで宣言しておく
もしくは引数で受け取る関数の 2 つ目以降の引数で渡す

パッと見騙されそうな変数宣言
ネット上のコード見てたらこういうのがありました

let x, y = 100, data

⇩ のように読んでから

let x = 100
let y = data

「え JavaScript でそんな代入できたっけ?」 と二度見
⇩ みたいにする必要があったはずだけどいつのまにか新機能できてた?

let [x, y] = [100, data]

10 秒くらい考えてから x と y と data を宣言して y に 100 を代入してるだけだと理解しました
自分では宣言をまとめて書くなんてしないからパッと見では脳内パースが正しくできませんでした
Python 書いた後だと特に紛らわしいですよね
マウス乗せたときだけスクロールバーを出す
:hover で overflow を切り替えるだけ
スクロールバーデザインも変えてモバイル風味にしてみた

webkit-scrollbar 系には opacity 効かないし 背景を透明にしても裏側は見れない
-webkit-scrollbar-thumb の background は設定できるけど transition でアニメーションしない
JavaScript で徐々に背景色の alpha 値変えればいけそうだけど CSS で収めたかったのでやってない

<!doctype html>

<style>
* {
box-sizing: border-box;
}

.box {
width: 200px;
height: 300px;
border: 2px solid #c4cf8a;
overflow: hidden;
}

.box:hover {
overflow: overlay;
}

.box::-webkit-scrollbar {
width: 6px;
height: 6px;
}

.box::-webkit-scrollbar-thumb {
background: #aaa;
border-radius: 5px;
}
</style>

<div class="box"></div>

<script>
const b = document.querySelector(".box")
b.innerHTML += ("12345".repeat(10) + "<br/>").repeat(100)
</script>
lit-html でリスナの this は eventContext で設定できる
カスタムエレメント中で render にこんなオプション付きで実行

    render() {
return render(this.template, this.shadowRoot, { eventContext: this })
}

eventContext: this を render の 3 つ目の引数に設定しておくと テンプレートの HTML に @XXXX で設定したリスナ実行時の this がそのカスタムエレメントになる
なにも設定しないと this はイベントが起きた要素

    get template() {
return html`
<div @click=${this.onClickDiv}>click me</div>
`
}

onClickDiv(eve) {
console.log(this)
}

こう書いたときの this が他メソッドと同じようにカスタムエレメント自身なので見やすい

テンプレート側でこうも書けるけど見づらいし忘れがちなので render で設定するほうがおすすめ

html`<div @click=${this.onClickDiv.bind(this)}></div>`

この方法だと render のたびに bind で作った新しい関数を設定してるから毎回リスナを再設定することにもなるしね
Python でクリップボードの REPL 出力を実行できる形式に変換する
import pyperclip

text = pyperclip.paste()
lines = text.splitlines()
lines = [line[4:] if line.startswith(">>>") or line.startswith("...") else "# " + line for line in lines]
pyperclip.copy("\n".join(lines))

⇩のような REPL の出力を

>>> class A: pass
...
>>> def x():
... return 1
...
>>> x()
1
>>> A()
<__main__.A object at 0x7f64c810be48>

⇩に変換する

class A: pass

def x():
return 1

x()
# 1
A()
# <__main__.A object at 0x7f64c810be48>

現在のクリップボードのテキストを変換するので REPL 出力をコピペするときに貼り付けの前にこれを実行する
REPL のフォーマットじゃなくて実行できる正しい Python 構文にしたいときに便利
複数文まとめて再実行するときにも使える
実行にはライブラリ pyperclip が必要

これまで web ページで変換ツールにしていたけど
1)ページ開いて
2)入力ボックスに貼り付けて
3)出力ボックスをコピーして
という手順が面倒でクリップボードのデータをそのまま変更したほうが楽そうなのでやってみた

クリップボード履歴管理ツールを使ってると変更前のも残るので便利
初回表示時にアニメーションしてしまう
表示の ON/OFF で CSS でスライドアニメーションするつくり
クラスのトグルで表示を切り替え
初期状態は localStorage の値次第

初期状態が ON のときにクラスをつけても初回表示の場合はアニメーションせず初期状態として表示や非表示になってるはず
なのになぜかアニメーションする

調べてみたら 別の箇所の初期化の途中で offsetHeight を参照してた
これがあるとその時点でレイアウト計算が行われるので それ以降にクラスを切り替えてtransition が設定されたプロパティが変更されるとアニメーションする

しかたないので アニメーション OFF の状態でレイアウト計算させるようにした

elem.classList.remove("animation")
elem.getClientRects()
elem.classList.add("animation")

アニメーションが OFF の状態でクラス変更なのでアニメーションは起きない
その後 アニメーションを ON にしてもそれ以降に変化はないのでアニメーションしない

ページ準備完了後に body に ready クラスをつけて transition は 「.ready some-elem」 みたいなロード後にのみ有効になるようにしたほうがいいかも

Chrome Extension の background scripts で module を使いたい
Chrome Extension の background scripts は通常こういう風に指定します

  "background": {
"scripts": ["bg.js"]
}

しかし これだと自動で作られた HTML に通常の JavaScript として実行されます
module ではないので import や export は syntax error です
今のところ module としてロードする機能はなさそうなので 自分で HTML ページを作って module としてロードする必要があります

  "background": {
"page": "bg.html"
}

<!doctype html>
<meta charset="utf-8"/>
<script src="bg.js" type="module"></script>
open と close だけ window がある
open や close は window.open や window.close ってよく書くけど
alert とか confirm とか parseInt とか fetch とか atob とか print とかは window はつけない

window を開いたり閉じたりするから必要そうな雰囲気あるけど 実際は window はグローバルオブジェクトなので alert などと扱いは一緒
open も alert も window あってもなくてもいい

だけどなぜかつい書いてしまうし 書いてる例が多い気がする
使えそうな Windows の環境変数
set

コマンドで環境変数リストが見れる
(たぶん)デフォルトで存在して どこかで使えそうな変数のまとめ
値はあくまでサンプル 設定によって変わるものもある

HOMEDRIVE=C:
HOMEPATH=\Users\testuser
SystemDrive=C:
SystemRoot=C:\WINDOWS
windir=C:\WINDOWS
USERNAME=testuser
USERPROFILE=C:\Users\testuser
PUBLIC=C:\Users\Public
ALLUSERSPROFILE=C:\ProgramData
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
TEMP=C:\Users\testuser\AppData\Local\Temp
TMP=C:\Users\testuser\AppData\Local\Temp
APPDATA=C:\Users\testuser\AppData\Roaming
LOCALAPPDATA=C:\Users\testuser\AppData\Local
DriverData=C:\Windows\System32\Drivers\DriverData
ComSpec=C:\WINDOWS\system32\cmd.exe
COMPUTERNAME=FRONTIER
USERDOMAIN=FRONTIER
LOGONSERVER=\\FRONTIER
OS=Windows_NT
PROMPT=$P$G
VisualStudioCode の Untitled-X の保存場所
ファイルに保存する前の Untitled-X (X は連番) が保存されてる場所

C:\Users\USER\AppData\Roaming\Code\Backups\XXXXX\untitled

ちゃんとファイルに保存されてるので 強制終了とかがあっても復元できる

Code フォルダが VSCode のデータがあるフォルダ
Electron だからこのフォルダを見つければ Mac や Linux でも中身の構造は同じだと思う

USER はユーザ名

XXXXX は unixtime かハッシュ値
たぶんハッシュ値はフォルダを開いたりワークスペースを開いたりした場合の ID で unixtime はフォルダなどを開いてないときのもの

untitled フォルダ内にはハッシュ値のファイル名になっていて Untilted-X 形式の名前じゃない
ただのテキストなので開いてみればわかる
JavaScript のグローバルオブジェクトのプロパティ
グローバルに存在する関数などを見てると機能が増えたことがわかりやすいので Chrome と Firefox で window のプロパティ一覧

{
let target = window
let name = "window"
while(target){
const keys = Object.keys(Object.getOwnPropertyDescriptors(target))
console.log(name, keys.sort())
target = target.__proto__
name = name + ".__proto__"
}
}

Chrome 73

window (820) [
"$",
"$$",
"$0",
"$1",
"$2",
"$3",
"$4",
"$_",
"$x",
"AbortController",
"AbortSignal",
"AnalyserNode",
"AnimationEvent",
"Array",
"ArrayBuffer",
"Atomics",
"Attr",
"Audio",
"AudioBuffer",
"AudioBufferSourceNode",
"AudioContext",
"AudioDestinationNode",
"AudioListener",
"AudioNode",
"AudioParam",
"AudioParamMap",
"AudioProcessingEvent",
"AudioScheduledSourceNode",
"AudioWorkletNode",
"BarProp",
"BaseAudioContext",
"BatteryManager",
"BeforeInstallPromptEvent",
"BeforeUnloadEvent",
"BigInt",
"BigInt64Array",
"BigUint64Array",
"BiquadFilterNode",
"Blob",
"BlobEvent",
"Boolean",
"BroadcastChannel",
"ByteLengthQueuingStrategy",
"CDATASection",
"CSS",
"CSSConditionRule",
"CSSFontFaceRule",
"CSSGroupingRule",
"CSSImageValue",
"CSSImportRule",
"CSSKeyframeRule",
"CSSKeyframesRule",
"CSSKeywordValue",
"CSSMathInvert",
"CSSMathMax",
"CSSMathMin",
"CSSMathNegate",
"CSSMathProduct",
"CSSMathSum",
"CSSMathValue",
"CSSMatrixComponent",
"CSSMediaRule",
"CSSNamespaceRule",
"CSSNumericArray",
"CSSNumericValue",
"CSSPageRule",
"CSSPerspective",
"CSSPositionValue",
"CSSRotate",
"CSSRule",
"CSSRuleList",
"CSSScale",
"CSSSkew",
"CSSSkewX",
"CSSSkewY",
"CSSStyleDeclaration",
"CSSStyleRule",
"CSSStyleSheet",
"CSSStyleValue",
"CSSSupportsRule",
"CSSTransformComponent",
"CSSTransformValue",
"CSSTranslate",
"CSSUnitValue",
"CSSUnparsedValue",
"CSSVariableReferenceValue",
"CanvasCaptureMediaStreamTrack",
"CanvasGradient",
"CanvasPattern",
"CanvasRenderingContext2D",
"ChannelMergerNode",
"ChannelSplitterNode",
"CharacterData",
"ClipboardEvent",
"CloseEvent",
"Comment",
"CompositionEvent",
"ConstantSourceNode",
"ConvolverNode",
"CountQueuingStrategy",
"Crypto",
"CryptoKey",
"CustomElementRegistry",
"CustomEvent",
"DOMError",
"DOMException",
"DOMImplementation",
"DOMMatrix",
"DOMMatrixReadOnly",
"DOMParser",
"DOMPoint",
"DOMPointReadOnly",
"DOMQuad",
"DOMRect",
"DOMRectList",
"DOMRectReadOnly",
"DOMStringList",
"DOMStringMap",
"DOMTokenList",
"DataTransfer",
"DataTransferItem",
"DataTransferItemList",
"DataView",
"Date",
"DelayNode",
"DeviceMotionEvent",
"DeviceOrientationEvent",
"Document",
"DocumentFragment",
"DocumentType",
"DragEvent",
"DynamicsCompressorNode",
"Element",
"EnterPictureInPictureEvent",
"Error",
"ErrorEvent",
"EvalError",
"Event",
"EventSource",
"EventTarget",
"External",
"File",
"FileList",
"FileReader",
"Float32Array",
"Float64Array",
"FocusEvent",
"FontFace",
"FontFaceSetLoadEvent",
"FormData",
"Function",
"GainNode",
"Gamepad",
"GamepadButton",
"GamepadEvent",
"GamepadHapticActuator",
"HTMLAllCollection",
"HTMLAnchorElement",
"HTMLAreaElement",
"HTMLAudioElement",
"HTMLBRElement",
"HTMLBaseElement",
"HTMLBodyElement",
"HTMLButtonElement",
"HTMLCanvasElement",
"HTMLCollection",
"HTMLContentElement",
"HTMLDListElement",
"HTMLDataElement",
"HTMLDataListElement",
"HTMLDetailsElement",
"HTMLDialogElement",
"HTMLDirectoryElement",
"HTMLDivElement",
"HTMLDocument",
"HTMLElement",
"HTMLEmbedElement",
"HTMLFieldSetElement",
"HTMLFontElement",
"HTMLFormControlsCollection",
"HTMLFormElement",
"HTMLFrameElement",
"HTMLFrameSetElement",
"HTMLHRElement",
"HTMLHeadElement",
"HTMLHeadingElement",
"HTMLHtmlElement",
"HTMLIFrameElement",
"HTMLImageElement",
"HTMLInputElement",
"HTMLLIElement",
"HTMLLabelElement",
"HTMLLegendElement",
"HTMLLinkElement",
"HTMLMapElement",
"HTMLMarqueeElement",
"HTMLMediaElement",
"HTMLMenuElement",
"HTMLMetaElement",
"HTMLMeterElement",
"HTMLModElement",
"HTMLOListElement",
"HTMLObjectElement",
"HTMLOptGroupElement",
"HTMLOptionElement",
"HTMLOptionsCollection",
"HTMLOutputElement",
"HTMLParagraphElement",
"HTMLParamElement",
"HTMLPictureElement",
"HTMLPreElement",
"HTMLProgressElement",
"HTMLQuoteElement",
"HTMLScriptElement",
"HTMLSelectElement",
"HTMLShadowElement",
"HTMLSlotElement",
"HTMLSourceElement",
"HTMLSpanElement",
"HTMLStyleElement",
"HTMLTableCaptionElement",
"HTMLTableCellElement",
"HTMLTableColElement",
"HTMLTableElement",
"HTMLTableRowElement",
"HTMLTableSectionElement",
"HTMLTemplateElement",
"HTMLTextAreaElement",
"HTMLTimeElement",
"HTMLTitleElement",
"HTMLTrackElement",
"HTMLUListElement",
"HTMLUnknownElement",
"HTMLVideoElement",
"HashChangeEvent",
"Headers",
"History",
"IDBCursor",
"IDBCursorWithValue",
"IDBDatabase",
"IDBFactory",
"IDBIndex",
"IDBKeyRange",
"IDBObjectStore",
"IDBOpenDBRequest",
"IDBRequest",
"IDBTransaction",
"IDBVersionChangeEvent",
"IIRFilterNode",
"IdleDeadline",
"Image",
"ImageBitmap",
"ImageBitmapRenderingContext",
"ImageCapture",
"ImageData",
"Infinity",
"InputDeviceCapabilities",
"InputDeviceInfo",
"InputEvent",
"Int16Array",
"Int32Array",
"Int8Array",
"IntersectionObserver",
"IntersectionObserverEntry",
"Intl",
"JSON",
"KeyboardEvent",
"Location",
"MIDIAccess",
"MIDIConnectionEvent",
"MIDIInput",
"MIDIInputMap",
"MIDIMessageEvent",
"MIDIOutput",
"MIDIOutputMap",
"MIDIPort",
"Map",
"Math",
"MediaCapabilities",
"MediaDeviceInfo",
"MediaDevices",
"MediaElementAudioSourceNode",
"MediaEncryptedEvent",
"MediaError",
"MediaList",
"MediaMetadata",
"MediaQueryList",
"MediaQueryListEvent",
"MediaRecorder",
"MediaSession",
"MediaSettingsRange",
"MediaSource",
"MediaStream",
"MediaStreamAudioDestinationNode",
"MediaStreamAudioSourceNode",
"MediaStreamEvent",
"MediaStreamTrack",
"MediaStreamTrackEvent",
"MessageChannel",
"MessageEvent",
"MessagePort",
"MimeType",
"MimeTypeArray",
"MouseEvent",
"MutationEvent",
"MutationObserver",
"MutationRecord",
"NaN",
"NamedNodeMap",
"Navigator",
"NetworkInformation",
"Node",
"NodeFilter",
"NodeIterator",
"NodeList",
"Notification",
"Number",
"Object",
"OfflineAudioCompletionEvent",
"OfflineAudioContext",
"OffscreenCanvas",
"OffscreenCanvasRenderingContext2D",
"Option",
"OscillatorNode",
"OverconstrainedError",
"PageTransitionEvent",
"PannerNode",
"Path2D",
"PaymentInstruments",
"PaymentManager",
"PaymentRequestUpdateEvent",
"Performance",
"PerformanceEntry",
"PerformanceLongTaskTiming",
"PerformanceMark",
"PerformanceMeasure",
"PerformanceNavigation",
"PerformanceNavigationTiming",
"PerformanceObserver",
"PerformanceObserverEntryList",
"PerformancePaintTiming",
"PerformanceResourceTiming",
"PerformanceServerTiming",
"PerformanceTiming",
"PeriodicWave",
"PermissionStatus",
"Permissions",
"PhotoCapabilities",
"PictureInPictureWindow",
"Plugin",
"PluginArray",
"PointerEvent",
"PopStateEvent",
"ProcessingInstruction",
"ProgressEvent",
"Promise",
"PromiseRejectionEvent",
"Proxy",
"PushManager",
"PushSubscription",
"PushSubscriptionOptions",
"RTCCertificate",
"RTCDTMFSender",
"RTCDTMFToneChangeEvent",
"RTCDataChannel",
"RTCDataChannelEvent",
"RTCIceCandidate",
"RTCPeerConnection",
"RTCPeerConnectionIceEvent",
"RTCRtpReceiver",
"RTCRtpSender",
"RTCRtpTransceiver",
"RTCSessionDescription",
"RTCStatsReport",
"RTCTrackEvent",
"RadioNodeList",
"Range",
"RangeError",
"ReadableStream",
"ReferenceError",
"Reflect",
"RegExp",
"RemotePlayback",
"ReportingObserver",
"Request",
"ResizeObserver",
"ResizeObserverEntry",
"Response",
"SVGAElement",
"SVGAngle",
"SVGAnimateElement",
"SVGAnimateMotionElement",
"SVGAnimateTransformElement",
"SVGAnimatedAngle",
"SVGAnimatedBoolean",
"SVGAnimatedEnumeration",
"SVGAnimatedInteger",
"SVGAnimatedLength",
"SVGAnimatedLengthList",
"SVGAnimatedNumber",
"SVGAnimatedNumberList",
"SVGAnimatedPreserveAspectRatio",
"SVGAnimatedRect",
"SVGAnimatedString",
"SVGAnimatedTransformList",
"SVGAnimationElement",
"SVGCircleElement",
"SVGClipPathElement",
"SVGComponentTransferFunctionElement",
"SVGDefsElement",
"SVGDescElement",
"SVGDiscardElement",
"SVGElement",
"SVGEllipseElement",
"SVGFEBlendElement",
"SVGFEColorMatrixElement",
"SVGFEComponentTransferElement",
"SVGFECompositeElement",
"SVGFEConvolveMatrixElement",
"SVGFEDiffuseLightingElement",
"SVGFEDisplacementMapElement",
"SVGFEDistantLightElement",
"SVGFEDropShadowElement",
"SVGFEFloodElement",
"SVGFEFuncAElement",
"SVGFEFuncBElement",
"SVGFEFuncGElement",
"SVGFEFuncRElement",
"SVGFEGaussianBlurElement",
"SVGFEImageElement",
"SVGFEMergeElement",
"SVGFEMergeNodeElement",
"SVGFEMorphologyElement",
"SVGFEOffsetElement",
"SVGFEPointLightElement",
"SVGFESpecularLightingElement",
"SVGFESpotLightElement",
"SVGFETileElement",
"SVGFETurbulenceElement",
"SVGFilterElement",
"SVGForeignObjectElement",
"SVGGElement",
"SVGGeometryElement",
"SVGGradientElement",
"SVGGraphicsElement",
"SVGImageElement",
"SVGLength",
"SVGLengthList",
"SVGLineElement",
"SVGLinearGradientElement",
"SVGMPathElement",
"SVGMarkerElement",
"SVGMaskElement",
"SVGMatrix",
"SVGMetadataElement",
"SVGNumber",
"SVGNumberList",
"SVGPathElement",
"SVGPatternElement",
"SVGPoint",
"SVGPointList",
"SVGPolygonElement",
"SVGPolylineElement",
"SVGPreserveAspectRatio",
"SVGRadialGradientElement",
"SVGRect",
"SVGRectElement",
"SVGSVGElement",
"SVGScriptElement",
"SVGSetElement",
"SVGStopElement",
"SVGStringList",
"SVGStyleElement",
"SVGSwitchElement",
"SVGSymbolElement",
"SVGTSpanElement",
"SVGTextContentElement",
"SVGTextElement",
"SVGTextPathElement",
"SVGTextPositioningElement",
"SVGTitleElement",
"SVGTransform",
"SVGTransformList",
"SVGUnitTypes",
"SVGUseElement",
"SVGViewElement",
"Screen",
"ScreenOrientation",
"ScriptProcessorNode",
"SecurityPolicyViolationEvent",
"Selection",
"Set",
"ShadowRoot",
"SharedArrayBuffer",
"SharedWorker",
"SourceBuffer",
"SourceBufferList",
"SpeechSynthesisErrorEvent",
"SpeechSynthesisEvent",
"SpeechSynthesisUtterance",
"StaticRange",
"StereoPannerNode",
"Storage",
"StorageEvent",
"String",
"StylePropertyMap",
"StylePropertyMapReadOnly",
"StyleSheet",
"StyleSheetList",
"SubtleCrypto",
"Symbol",
"SyncManager",
"SyntaxError",
"TaskAttributionTiming",
"Text",
"TextDecoder",
"TextDecoderStream",
"TextEncoder",
"TextEncoderStream",
"TextEvent",
"TextMetrics",
"TextTrack",
"TextTrackCue",
"TextTrackCueList",
"TextTrackList",
"TimeRanges",
"Touch",
"TouchEvent",
"TouchList",
"TrackEvent",
"TransformStream",
"TransitionEvent",
"TreeWalker",
"TypeError",
"UIEvent",
"URIError",
"URL",
"URLSearchParams",
"Uint16Array",
"Uint32Array",
"Uint8Array",
"Uint8ClampedArray",
"UserActivation",
"VTTCue",
"ValidityState",
"VisualViewport",
"WaveShaperNode",
"WeakMap",
"WeakSet",
"WebAssembly",
"WebGL2RenderingContext",
"WebGLActiveInfo",
"WebGLBuffer",
"WebGLContextEvent",
"WebGLFramebuffer",
"WebGLProgram",
"WebGLQuery",
"WebGLRenderbuffer",
"WebGLRenderingContext",
"WebGLSampler",
"WebGLShader",
"WebGLShaderPrecisionFormat",
"WebGLSync",
"WebGLTexture",
"WebGLTransformFeedback",
"WebGLUniformLocation",
"WebGLVertexArrayObject",
"WebKitCSSMatrix",
"WebKitMutationObserver",
"WebSocket",
"WheelEvent",
"Window",
"Worker",
"WritableStream",
"XMLDocument",
"XMLHttpRequest",
"XMLHttpRequestEventTarget",
"XMLHttpRequestUpload",
"XMLSerializer",
"XPathEvaluator",
"XPathExpression",
"XPathResult",
"XSLTProcessor",
"alert",
"atob",
"blur",
"btoa",
"cancelAnimationFrame",
"cancelIdleCallback",
"captureEvents",
"chrome",
"clear",
"clearInterval",
"clearTimeout",
"clientInformation",
"close",
"closed",
"confirm",
"console",
"copy",
"createImageBitmap",
"crypto",
"customElements",
"debug",
"decodeURI",
"decodeURIComponent",
"defaultStatus",
"defaultstatus",
"devicePixelRatio",
"dir",
"dirxml",
"document",
"encodeURI",
"encodeURIComponent",
"escape",
"eval",
"event",
"external",
"fetch",
"find",
"focus",
"frameElement",
"frames",
"getComputedStyle",
"getEventListeners",
"getSelection",
"globalThis",
"history",
"indexedDB",
"innerHeight",
"innerWidth",
"inspect",
"isFinite",
"isNaN",
"isSecureContext",
"keys",
"length",
"localStorage",
"location",
"locationbar",
"matchMedia",
"menubar",
"monitor",
"monitorEvents",
"moveBy",
"moveTo",
"name",
"navigator",
"offscreenBuffering",
"onabort",
"onafterprint",
"onanimationend",
"onanimationiteration",
"onanimationstart",
"onappinstalled",
"onauxclick",
"onbeforeinstallprompt",
"onbeforeprint",
"onbeforeunload",
"onblur",
"oncancel",
"oncanplay",
"oncanplaythrough",
"onchange",
"onclick",
"onclose",
"oncontextmenu",
"oncuechange",
"ondblclick",
"ondevicemotion",
"ondeviceorientation",
"ondeviceorientationabsolute",
"ondrag",
"ondragend",
"ondragenter",
"ondragleave",
"ondragover",
"ondragstart",
"ondrop",
"ondurationchange",
"onemptied",
"onended",
"onerror",
"onfocus",
"ongotpointercapture",
"onhashchange",
"oninput",
"oninvalid",
"onkeydown",
"onkeypress",
"onkeyup",
"onlanguagechange",
"onload",
"onloadeddata",
"onloadedmetadata",
"onloadstart",
"onlostpointercapture",
"onmessage",
"onmessageerror",
"onmousedown",
"onmouseenter",
"onmouseleave",
"onmousemove",
"onmouseout",
"onmouseover",
"onmouseup",
"onmousewheel",
"onoffline",
"ononline",
"onpagehide",
"onpageshow",
"onpause",
"onplay",
"onplaying",
"onpointercancel",
"onpointerdown",
"onpointerenter",
"onpointerleave",
"onpointermove",
"onpointerout",
"onpointerover",
"onpointerup",
"onpopstate",
"onprogress",
"onratechange",
"onrejectionhandled",
"onreset",
"onresize",
"onscroll",
"onsearch",
"onseeked",
"onseeking",
"onselect",
"onselectionchange",
"onselectstart",
"onstalled",
"onstorage",
"onsubmit",
"onsuspend",
"ontimeupdate",
"ontoggle",
"ontransitionend",
"onunhandledrejection",
"onunload",
"onvolumechange",
"onwaiting",
"onwebkitanimationend",
"onwebkitanimationiteration",
"onwebkitanimationstart",
"onwebkittransitionend",
"onwheel",
"open",
"openDatabase",
"opener",
"origin",
"outerHeight",
"outerWidth",
"pageXOffset",
"pageYOffset",
"parent",
"parseFloat",
"parseInt",
"performance",
"personalbar",
"postMessage",
"print",
"profile",
"profileEnd",
"prompt",
"queryObjects",
"queueMicrotask",
"releaseEvents",
"requestAnimationFrame",
"requestIdleCallback",
"resizeBy",
"resizeTo",
"screen",
"screenLeft",
"screenTop",
"screenX",
"screenY",
"scroll",
"scrollBy",
"scrollTo",
"scrollX",
"scrollY",
"scrollbars",
"self",
"sessionStorage",
"setInterval",
"setTimeout",
"speechSynthesis",
"status",
"statusbar",
"stop",
"styleMedia",
"table",
"toolbar",
"top",
"undebug",
"undefined",
"unescape",
"unmonitor",
"unmonitorEvents",
"values",
"visualViewport",
"webkitCancelAnimationFrame",
"webkitMediaStream",
"webkitRTCPeerConnection",
"webkitRequestAnimationFrame",
"webkitRequestFileSystem",
"webkitResolveLocalFileSystemURL",
"webkitSpeechGrammar",
"webkitSpeechGrammarList",
"webkitSpeechRecognition",
"webkitSpeechRecognitionError",
"webkitSpeechRecognitionEvent",
"webkitStorageInfo",
"webkitURL",
"window"
]
window.__proto__ (3)
["PERSISTENT", "TEMPORARY", "constructor"]
window.__proto__.__proto__
["constructor"]
window.__proto__.__proto__.__proto__ (4)
["addEventListener", "constructor", "dispatchEvent", "removeEventListener"]
window.__proto__.__proto__.__proto__.__proto__ (12)
["__defineGetter__", "__defineSetter__", "__lookupGetter__", "__lookupSetter__",
"__proto__", "constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable",
"toLocaleString", "toString", "valueOf"]

Firefox 66

window Array(771) [
"AbortController",
"AbortSignal",
"AnalyserNode",
"Animation",
"AnimationEffect",
"AnimationEvent",
"AnimationPlaybackEvent",
"Array",
"ArrayBuffer",
"Attr",
"Audio",
"AudioBuffer",
"AudioBufferSourceNode",
"AudioContext",
"AudioDestinationNode",
"AudioListener",
"AudioNode",
"AudioParam",
"AudioProcessingEvent",
"AudioScheduledSourceNode",
"BarProp",
"BaseAudioContext",
"BatteryManager",
"BeforeUnloadEvent",
"BiquadFilterNode",
"Blob",
"BlobEvent",
"Boolean",
"BroadcastChannel",
"ByteLengthQueuingStrategy",
"CDATASection",
"CSS",
"CSS2Properties",
"CSSConditionRule",
"CSSCounterStyleRule",
"CSSFontFaceRule",
"CSSFontFeatureValuesRule",
"CSSGroupingRule",
"CSSImportRule",
"CSSKeyframeRule",
"CSSKeyframesRule",
"CSSMediaRule",
"CSSMozDocumentRule",
"CSSNamespaceRule",
"CSSPageRule",
"CSSRule",
"CSSRuleList",
"CSSStyleDeclaration",
"CSSStyleRule",
"CSSStyleSheet",
"CSSSupportsRule",
"Cache",
"CacheStorage",
"CanvasCaptureMediaStream",
"CanvasGradient",
"CanvasPattern",
"CanvasRenderingContext2D",
"CaretPosition",
"ChannelMergerNode",
"ChannelSplitterNode",
"CharacterData",
"ClipboardEvent",
"CloseEvent",
"Comment",
"CompositionEvent",
"ConstantSourceNode",
"ConvolverNode",
"CountQueuingStrategy",
"Crypto",
"CryptoKey",
"CustomElementRegistry",
"CustomEvent",
"DOMError",
"DOMException",
"DOMImplementation",
"DOMMatrix",
"DOMMatrixReadOnly",
"DOMParser",
"DOMPoint",
"DOMPointReadOnly",
"DOMQuad",
"DOMRect",
"DOMRectList",
"DOMRectReadOnly",
"DOMRequest",
"DOMStringList",
"DOMStringMap",
"DOMTokenList",
"DataTransfer",
"DataTransferItem",
"DataTransferItemList",
"DataView",
"Date",
"DelayNode",
"DeviceMotionEvent",
"DeviceOrientationEvent",
"Directory",
"Document",
"DocumentFragment",
"DocumentType",
"DragEvent",
"DynamicsCompressorNode",
"Element",
"Error",
"ErrorEvent",
"EvalError",
"Event",
"EventSource",
"EventTarget",
"File",
"FileList",
"FileReader",
"FileSystem",
"FileSystemDirectoryEntry",
"FileSystemDirectoryReader",
"FileSystemEntry",
"FileSystemFileEntry",
"Float32Array",
"Float64Array",
"FocusEvent",
"FontFace",
"FontFaceSet",
"FontFaceSetLoadEvent",
"FormData",
"Function",
"GainNode",
"Gamepad",
"GamepadButton",
"GamepadEvent",
"GamepadHapticActuator",
"GamepadPose",
"HTMLAllCollection",
"HTMLAnchorElement",
"HTMLAreaElement",
"HTMLAudioElement",
"HTMLBRElement",
"HTMLBaseElement",
"HTMLBodyElement",
"HTMLButtonElement",
"HTMLCanvasElement",
"HTMLCollection",
"HTMLDListElement",
"HTMLDataElement",
"HTMLDataListElement",
"HTMLDetailsElement",
"HTMLDirectoryElement",
"HTMLDivElement",
"HTMLDocument",
"HTMLElement",
"HTMLEmbedElement",
"HTMLFieldSetElement",
"HTMLFontElement",
"HTMLFormControlsCollection",
"HTMLFormElement",
"HTMLFrameElement",
"HTMLFrameSetElement",
"HTMLHRElement",
"HTMLHeadElement",
"HTMLHeadingElement",
"HTMLHtmlElement",
"HTMLIFrameElement",
"HTMLImageElement",
"HTMLInputElement",
"HTMLLIElement",
"HTMLLabelElement",
"HTMLLegendElement",
"HTMLLinkElement",
"HTMLMapElement",
"HTMLMarqueeElement",
"HTMLMediaElement",
"HTMLMenuElement",
"HTMLMenuItemElement",
"HTMLMetaElement",
"HTMLMeterElement",
"HTMLModElement",
"HTMLOListElement",
"HTMLObjectElement",
"HTMLOptGroupElement",
"HTMLOptionElement",
"HTMLOptionsCollection",
"HTMLOutputElement",
"HTMLParagraphElement",
"HTMLParamElement",
"HTMLPictureElement",
"HTMLPreElement",
"HTMLProgressElement",
"HTMLQuoteElement",
"HTMLScriptElement",
"HTMLSelectElement",
"HTMLSlotElement",
"HTMLSourceElement",
"HTMLSpanElement",
"HTMLStyleElement",
"HTMLTableCaptionElement",
"HTMLTableCellElement",
"HTMLTableColElement",
"HTMLTableElement",
"HTMLTableRowElement",
"HTMLTableSectionElement",
"HTMLTemplateElement",
"HTMLTextAreaElement",
"HTMLTimeElement",
"HTMLTitleElement",
"HTMLTrackElement",
"HTMLUListElement",
"HTMLUnknownElement",
"HTMLVideoElement",
"HashChangeEvent",
"Headers",
"History",
"IDBCursor",
"IDBCursorWithValue",
"IDBDatabase",
"IDBFactory",
"IDBFileHandle",
"IDBFileRequest",
"IDBIndex",
"IDBKeyRange",
"IDBMutableFile",
"IDBObjectStore",
"IDBOpenDBRequest",
"IDBRequest",
"IDBTransaction",
"IDBVersionChangeEvent",
"IIRFilterNode",
"IdleDeadline",
"Image",
"ImageBitmap",
"ImageBitmapRenderingContext",
"ImageData",
"Infinity",
"InputEvent",
"InstallTrigger",
"Int16Array",
"Int32Array",
"Int8Array",
"InternalError",
"IntersectionObserver",
"IntersectionObserverEntry",
"Intl",
"JSON",
"KeyEvent",
"KeyboardEvent",
"KeyframeEffect",
"Location",
"Map",
"Math",
"MediaCapabilities",
"MediaCapabilitiesInfo",
"MediaDeviceInfo",
"MediaDevices",
"MediaElementAudioSourceNode",
"MediaEncryptedEvent",
"MediaError",
"MediaKeyError",
"MediaKeyMessageEvent",
"MediaKeySession",
"MediaKeyStatusMap",
"MediaKeySystemAccess",
"MediaKeys",
"MediaList",
"MediaQueryList",
"MediaQueryListEvent",
"MediaRecorder",
"MediaRecorderErrorEvent",
"MediaSource",
"MediaStream",
"MediaStreamAudioDestinationNode",
"MediaStreamAudioSourceNode",
"MediaStreamEvent",
"MediaStreamTrack",
"MediaStreamTrackEvent",
"MessageChannel",
"MessageEvent",
"MessagePort",
"MimeType",
"MimeTypeArray",
"MouseEvent",
"MouseScrollEvent",
"MutationEvent",
"MutationObserver",
"MutationRecord",
"NaN",
"NamedNodeMap",
"Navigator",
"Node",
"NodeFilter",
"NodeIterator",
"NodeList",
"Notification",
"NotifyPaintEvent",
"Number",
"Object",
"OfflineAudioCompletionEvent",
"OfflineAudioContext",
"Option",
"OscillatorNode",
"PageTransitionEvent",
"PaintRequest",
"PaintRequestList",
"PannerNode",
"Path2D",
"Performance",
"PerformanceEntry",
"PerformanceMark",
"PerformanceMeasure",
"PerformanceNavigation",
"PerformanceNavigationTiming",
"PerformanceObserver",
"PerformanceObserverEntryList",
"PerformanceResourceTiming",
"PerformanceTiming",
"PeriodicWave",
"PermissionStatus",
"Permissions",
"Plugin",
"PluginArray",
"PointerEvent",
"PopStateEvent",
"PopupBlockedEvent",
"ProcessingInstruction",
"ProgressEvent",
"Promise",
"Proxy",
"PushManager",
"PushSubscription",
"PushSubscriptionOptions",
"RTCCertificate",
"RTCDTMFSender",
"RTCDTMFToneChangeEvent",
"RTCDataChannel",
"RTCDataChannelEvent",
"RTCIceCandidate",
"RTCPeerConnection",
"RTCPeerConnectionIceEvent",
"RTCRtpReceiver",
"RTCRtpSender",
"RTCRtpTransceiver",
"RTCSessionDescription",
"RTCStatsReport",
"RTCTrackEvent",
"RadioNodeList",
"Range",
"RangeError",
"ReadableStream",
"ReferenceError",
"Reflect",
"RegExp",
"Request",
"Response",
"SVGAElement",
"SVGAngle",
"SVGAnimateElement",
"SVGAnimateMotionElement",
"SVGAnimateTransformElement",
"SVGAnimatedAngle",
"SVGAnimatedBoolean",
"SVGAnimatedEnumeration",
"SVGAnimatedInteger",
"SVGAnimatedLength",
"SVGAnimatedLengthList",
"SVGAnimatedNumber",
"SVGAnimatedNumberList",
"SVGAnimatedPreserveAspectRatio",
"SVGAnimatedRect",
"SVGAnimatedString",
"SVGAnimatedTransformList",
"SVGAnimationElement",
"SVGCircleElement",
"SVGClipPathElement",
"SVGComponentTransferFunctionElement",
"SVGDefsElement",
"SVGDescElement",
"SVGElement",
"SVGEllipseElement",
"SVGFEBlendElement",
"SVGFEColorMatrixElement",
"SVGFEComponentTransferElement",
"SVGFECompositeElement",
"SVGFEConvolveMatrixElement",
"SVGFEDiffuseLightingElement",
"SVGFEDisplacementMapElement",
"SVGFEDistantLightElement",
"SVGFEDropShadowElement",
"SVGFEFloodElement",
"SVGFEFuncAElement",
"SVGFEFuncBElement",
"SVGFEFuncGElement",
"SVGFEFuncRElement",
"SVGFEGaussianBlurElement",
"SVGFEImageElement",
"SVGFEMergeElement",
"SVGFEMergeNodeElement",
"SVGFEMorphologyElement",
"SVGFEOffsetElement",
"SVGFEPointLightElement",
"SVGFESpecularLightingElement",
"SVGFESpotLightElement",
"SVGFETileElement",
"SVGFETurbulenceElement",
"SVGFilterElement",
"SVGForeignObjectElement",
"SVGGElement",
"SVGGeometryElement",
"SVGGradientElement",
"SVGGraphicsElement",
"SVGImageElement",
"SVGLength",
"SVGLengthList",
"SVGLineElement",
"SVGLinearGradientElement",
"SVGMPathElement",
"SVGMarkerElement",
"SVGMaskElement",
"SVGMatrix",
"SVGMetadataElement",
"SVGNumber",
"SVGNumberList",
"SVGPathElement",
"SVGPathSegList",
"SVGPatternElement",
"SVGPoint",
"SVGPointList",
"SVGPolygonElement",
"SVGPolylineElement",
"SVGPreserveAspectRatio",
"SVGRadialGradientElement",
"SVGRect",
"SVGRectElement",
"SVGSVGElement",
"SVGScriptElement",
"SVGSetElement",
"SVGStopElement",
"SVGStringList",
"SVGStyleElement",
"SVGSwitchElement",
"SVGSymbolElement",
"SVGTSpanElement",
"SVGTextContentElement",
"SVGTextElement",
"SVGTextPathElement",
"SVGTextPositioningElement",
"SVGTitleElement",
"SVGTransform",
"SVGTransformList",
"SVGUnitTypes",
"SVGUseElement",
"SVGViewElement",
"SVGZoomAndPan",
"Screen",
"ScreenOrientation",
"ScriptProcessorNode",
"ScrollAreaEvent",
"SecurityPolicyViolationEvent",
"Selection",
"ServiceWorker",
"ServiceWorkerRegistration",
"Set",
"ShadowRoot",
"SharedWorker",
"SourceBuffer",
"SourceBufferList",
"SpeechSynthesis",
"SpeechSynthesisErrorEvent",
"SpeechSynthesisEvent",
"SpeechSynthesisUtterance",
"SpeechSynthesisVoice",
"StereoPannerNode",
"Storage",
"StorageEvent",
"String",
"StyleSheet",
"StyleSheetList",
"SubtleCrypto",
"Symbol",
"SyntaxError",
"Text",
"TextDecoder",
"TextEncoder",
"TextMetrics",
"TextTrack",
"TextTrackCue",
"TextTrackCueList",
"TextTrackList",
"TimeEvent",
"TimeRanges",
"TrackEvent",
"TransitionEvent",
"TreeWalker",
"TypeError",
"UIEvent",
"URIError",
"URL",
"URLSearchParams",
"Uint16Array",
"Uint32Array",
"Uint8Array",
"Uint8ClampedArray",
"VRDisplay",
"VRDisplayCapabilities",
"VRDisplayEvent",
"VREyeParameters",
"VRFieldOfView",
"VRFrameData",
"VRPose",
"VRStageParameters",
"VTTCue",
"VTTRegion",
"ValidityState",
"VideoPlaybackQuality",
"VisualViewport",
"WaveShaperNode",
"WeakMap",
"WeakSet",
"WebAssembly",
"WebGL2RenderingContext",
"WebGLActiveInfo",
"WebGLBuffer",
"WebGLContextEvent",
"WebGLFramebuffer",
"WebGLProgram",
"WebGLQuery",
"WebGLRenderbuffer",
"WebGLRenderingContext",
"WebGLSampler",
"WebGLShader",
"WebGLShaderPrecisionFormat",
"WebGLSync",
"WebGLTexture",
"WebGLTransformFeedback",
"WebGLUniformLocation",
"WebGLVertexArrayObject",
"WebKitCSSMatrix",
"WebSocket",
"WheelEvent",
"Window",
"Worker",
"XMLDocument",
"XMLHttpRequest",
"XMLHttpRequestEventTarget",
"XMLHttpRequestUpload",
"XMLSerializer",
"XPathEvaluator",
"XPathExpression",
"XPathResult",
"XSLTProcessor",
"alert",
"atob",
"blur",
"btoa",
"caches",
"cancelAnimationFrame",
"cancelIdleCallback",
"captureEvents",
"clearInterval",
"clearTimeout",
"close",
"closed",
"confirm",
"console",
"content",
"createImageBitmap",
"crypto",
"customElements",
"decodeURI",
"decodeURIComponent",
"devicePixelRatio",
"document",
"dump",
"encodeURI",
"encodeURIComponent",
"escape",
"eval",
"event",
"external",
"fetch",
"find",
"focus",
"frameElement",
"frames",
"fullScreen",
"getComputedStyle",
"getDefaultComputedStyle",
"getSelection",
"history",
"indexedDB",
"innerHeight",
"innerWidth",
"isFinite",
"isNaN",
"isSecureContext",
"length",
"localStorage",
"location",
"locationbar",
"matchMedia",
"menubar",
"moveBy",
"moveTo",
"mozInnerScreenX",
"mozInnerScreenY",
"mozPaintCount",
"mozRTCIceCandidate",
"mozRTCPeerConnection",
"mozRTCSessionDescription",
"name",
"navigator",
"netscape",
"onabort",
"onabsolutedeviceorientation",
"onafterprint",
"onanimationcancel",
"onanimationend",
"onanimationiteration",
"onanimationstart",
"onauxclick",
"onbeforeprint",
"onbeforeunload",
"onblur",
"oncanplay",
"oncanplaythrough",
"onchange",
"onclick",
"onclose",
"oncontextmenu",
"ondblclick",
"ondevicelight",
"ondevicemotion",
"ondeviceorientation",
"ondeviceproximity",
"ondrag",
"ondragend",
"ondragenter",
"ondragexit",
"ondragleave",
"ondragover",
"ondragstart",
"ondrop",
"ondurationchange",
"onemptied",
"onended",
"onerror",
"onfocus",
"ongotpointercapture",
"onhashchange",
"oninput",
"oninvalid",
"onkeydown",
"onkeypress",
"onkeyup",
"onlanguagechange",
"onload",
"onloadeddata",
"onloadedmetadata",
"onloadend",
"onloadstart",
"onlostpointercapture",
"onmessage",
"onmessageerror",
"onmousedown",
"onmouseenter",
"onmouseleave",
"onmousemove",
"onmouseout",
"onmouseover",
"onmouseup",
"onmozfullscreenchange",
"onmozfullscreenerror",
"onoffline",
"ononline",
"onpagehide",
"onpageshow",
"onpause",
"onplay",
"onplaying",
"onpointercancel",
"onpointerdown",
"onpointerenter",
"onpointerleave",
"onpointermove",
"onpointerout",
"onpointerover",
"onpointerup",
"onpopstate",
"onprogress",
"onratechange",
"onreset",
"onresize",
"onscroll",
"onseeked",
"onseeking",
"onselect",
"onselectstart",
"onshow",
"onstalled",
"onstorage",
"onsubmit",
"onsuspend",
"ontimeupdate",
"ontoggle",
"ontransitioncancel",
"ontransitionend",
"ontransitionrun",
"ontransitionstart",
"onunload",
"onuserproximity",
"onvolumechange",
"onvrdisplayactivate",
"onvrdisplayconnect",
"onvrdisplaydeactivate",
"onvrdisplaydisconnect",
"onvrdisplaypresentchange",
"onwaiting",
"onwebkitanimationend",
"onwebkitanimationiteration",
"onwebkitanimationstart",
"onwebkittransitionend",
"onwheel",
"open",
"opener",
"origin",
"outerHeight",
"outerWidth",
"pageXOffset",
"pageYOffset",
"parent",
"parseFloat",
"parseInt",
"performance",
"personalbar",
"postMessage",
"print",
"prompt",
"releaseEvents",
"requestAnimationFrame",
"requestIdleCallback",
"resizeBy",
"resizeTo",
"screen",
"screenLeft",
"screenTop",
"screenX",
"screenY",
"scroll",
"scrollBy",
"scrollByLines",
"scrollByPages",
"scrollMaxX",
"scrollMaxY",
"scrollTo",
"scrollX",
"scrollY",
"scrollbars",
"self",
"sessionStorage",
"setInterval",
"setResizable",
"setTimeout",
"sidebar",
"sizeToContent",
"speechSynthesis",
"status",
"statusbar",
"stop",
"toolbar",
"top",
"undefined",
"unescape",
"uneval",
"updateCommands",
"window"
]
window.__proto__
Array [ "constructor" ]
window.__proto__.__proto__
Array []
window.__proto__.__proto__.__proto__
Array(4) [ "addEventListener", "constructor", "dispatchEvent", "removeEventListener" ]
window.__proto__.__proto__.__proto__.__proto__
Array(13) [ "__defineGetter__", "__defineSetter__", "__lookupGetter__", "__lookupSetter__",
"__proto__", "constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable",
"toLocaleString", "toSource", "toString", "valueOf" ]
EC2 サーバの ssh 接続を自動切断されないようにする
サーバ側で自動切断設定してるのかと sshd の設定を切断されないローカル VM と見比べても特に違いはなし

調べても日本語の個人サイトでは人によって書いてることが違ってどれが正しいかわかりません
設定は Server と Client どっちでもいいと書いてたり 理由や説明もなく動いたからと貼り付けてるだけでよくわからなかったので StackOveflow に行くといい回答がありました
やっぱり技術系の調べ物は英語のほうがいいですね

https://stackoverflow.com/questions/7210011/amazon-ec2-ssh-timeout-due-inactivity

EC2 サーバの設定ではなく AWS が一定時間通信がないと自動で切断するようです
それも リージョンによって間隔が違って短いと 1 分の通信なしで切られるそうです
ということで 50 秒ごとにサーバと疎通確認の通信を送っていればサーバから通信がないからと切断されることがなくなるようです

ServerAliveInterval 50

これをクライアントの ~/.ssh/config に追記します

JavaScript で if 式
あってほしいと思ってるのに JavaScript には if 式がありません
ただ eval は最後に評価した値が返ってくることを利用すれば

const x = eval(`
if(1) 1
else 2
`)
console.log(x)
// 1

const y = eval(`
if(0) 1
else 2
`)
console.log(y)
// 2
簡単に別タイムゾーンの日本時間を調べる
ネットを見てて 「20:00 UTC」 「15:30 PDT」 とか書いてても日本で何時なのかがぱっとわかりません
UTC ならよく扱うので 9 時間進めたのが日本だとわかりますがそれ以外はわかる気がしません
ググって何時間の時間差かを確認して計算ってするのも面倒です

JavaScript の Date 型でいけるんじゃない?と思ってやってみると

new Date("1/1/1 15:30 PDT")
// Tue Jan 02 2001 07:30:00 GMT+0900 (日本標準時)

とできました

基本ブラウザ使ってる最中なので F12 → 上のように調べたい時刻とタイムゾーンを入力 ですぐわかるのが便利ですね
日付はいらないのですが必須なので楽にかける 1/1/1 にしてます

最近の Chrome は実行前に結果プレビューしてくれるのでいちいちエンター押して複数回実行しなくても 日付の文字を変えるとその場で結果も変わるのもいいところです
util.promisify(child_process.exec)
> node -e "util.promisify(child_process.exec)(`node -e 'console.log(1);console.error(2)'`).then((...x) => console.log('T', x), (...x) => console.log('F', x))"
T [ { stdout: '1\n', stderr: '2\n' } ]

正常終了 exitcode が 0 のときは stdout, stderr がプロパティのオブジェクトを then の引数で受け取れる
それぞれに出力が入ってる
基本行末に改行があるので === するときは trim 必要なのに注意

> node -e "util.promisify(child_process.exec)(`node -e 'console.log(1);console.error(2);process.exit(1)'`).then((...x) => console.log('T', x), (...x) => console.log('F', x))"
F [ { Error: Command failed: node -e 'console.log(1);console.error(2);process.exit(1)'
2


at ChildProcess.exithandler (child_process.js:294:12)
at ChildProcess.emit (events.js:189:13)
at maybeClose (internal/child_process.js:970:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:259:5)
killed: false,
code: 1,
signal: null,
cmd:
'node -e \'console.log(1);console.error(2);process.exit(1)\'',
stdout: '1\n',
stderr: '2\n' } ]

エラー終了 exitcode が 0 でないときは エラーオブジェクトを catch の引数で受け取れる
code プロパティに exitcode
stdout/stderr に各出力が入ってる
エラーのメッセージは stderr が使われる
コンソールで const などで宣言したときは返り値が undefined
const x = 10
// undefined

その前に値を評価しておくと

10 * 10
const v = 10
// 100

undefined で上書きされない

明示的に undefined を評価すると

1 + 1
undefined
// undefined

undefined になる

関数定義だと

1 + 1
function f(){}
// 2

変数宣言と同じくその前の評価結果

評価する式がなにもないと

/**/
// undefined

ということは

変数宣言や関数の定義の場合は無視して最後に評価した結果の値
最後の値がない場合は undefined

Chrome だけじゃなく Firefox もおなじみたい
GoogleMaps API で開発用のみモードも使えない時がある?
ちょうど GoogleMaps がゼンリンと契約やめたと噂になってた頃
API キーなしで使うと for development purposes only と表示されて暗い画面がでていて見づらいなりにも使えていたのですが 全部灰色の画面で全く見えなくなりました

衛星写真を画像処理したものから自動生成してるらしいことも言われてましたし 大きく変わったみたいなので API 周りも変わって開発用でも API キー必要になるのかと思ったのですが 今見たら暗い画面で表示できていました
なにか条件があるのかな

ところで 新しい GoogleMaps は世間的に不評みたいですが個人的には見やすくなってる部分も多いと思うので良いと思ってます
機械による自動化はどんどんすべきだと思うので 衛星画像からの自動検出で道路を判断するとか先進的で期待です
変わったばかりの最初で完璧できるわけはないと思いますしここからの進化が期待ですね

確かこの変更がある前の GoogleMaps が変わる予定 みたいな発表ではユーザが情報を投稿したり修正できるみたいな OpenStreetMap に近そうなことを言ってたと思うので 完全自動では難しいところはユーザ任せなのかもですね
OpenStreetMap とか Wikipedia とかユーザ任せなものでもうまく言ってるのは多いですし 規模が大きいのはユーザ任せのほうがいいのかも
当たり前のように使ってましたが そもそもお金払ってるわけでもない無料サービスですし 過剰なサービスを要求するほうがおかしくて 地図会社と契約してるクオリティじゃなくて画像から自動検出したものでも本来十分なところですよね
(API のクレカ設定しないと無料範囲すら使わせてくれないのはどうにかしてほしいですけど)
くるくる回る loading アイコンの WebComponent
customElements.define(
"spin-loading",
class extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: "open" }).innerHTML = `
<style>
#loading {
display: block;
box-sizing: border-box;
width: var(--size, 100px);
height: var(--size, 100px);
border: 0 solid transparent;
border-bottom-width: calc(var(--size) / 2);
border-right: var(--width, 6px) solid var(--color, #d4ba00);
border-radius: 50%;
animation: loading var(--speed, 0.6s) linear 0s infinite;
}

@keyframes loading{
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
</style>
<div id="loading"></div>
`
}
}
)

使用例

<!doctype html>

<script src="loading.js"></script>

<style>
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
width: 100vw;
height: 100vh;
background: #333;
}
spin-loading{
--size: 100px;
--speed: 0.6s;
--width: 6px;
--color: #d4ba00;
}
</style>

<spin-loading></spin-loading>
ベクトルの次元って?
◯次元ベクトルとかいう言葉をネットで見かけて 「あれ?ベクトルの次元ってなんだっけ」 とよくわからなくなりました

2 次元なら (10, -3) みたいに 2 数字があって二次元平面上の任意の座標を表せるやつだっけ?
つまり 1 次元は単純な数字 1 つだけで通常の数値と一緒?

ただ配列のことを言語によっては Vector と表現してたはず
Hack とか C++ とか

そう考えると 2 次元ベクトル= 2次元配列で [[1, 2], [3, 4], [5, 6]] とかのこと?
ただ 2 次元になると Matrix と呼ばれる気もします
1 次元だから Vector で Vector (配列) の要素数=次元と考えるのがあってるようにも思えます

数学っぽい話は難しいですね
文字列を N 文字ごとに分割したい 他
文字列を N 文字ごとに分割したい

const splitNchars = (str, n) => str.split(new RegExp(`(.{${~~n}})`)).filter(e => e)

splitNchars("abcdefg", 2)
// ["ab", "cd", "ef", "g"]

文字列を N 文字ごとに改行したい

splitNchars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 13).join("\n")
// abcdefghijklm
// nopqrstuvwxyz
// ABCDEFGHIJKLM
// NOPQRSTUVWXYZ
// 1234567890

文字列を N 個に分割したい

const splitNstrings = (str, n) => {
const arr = splitNchars(str, Math.ceil(str.length / n))
return [...arr, ...Array(n - arr.length).fill("")]
}

splitNstrings("abcdefg", 2)
// ["abcd", "efg"]
Nodist で yarn 使うときのパス
Windows に Nodist で Node.js を入れて yarn でパッケージをグローバルインストールすると自分でパスを通さないといけません
普通に Nodist をインストールすると 「C:\Program Files (x86)\Nodist」 にインストールされます
node.exe や npm.exe は 「C:\Program Files (x86)\Nodist\bin」 に保存されます
npm でグローバルにインストールしたパッケージのコマンドもここに配置されます
npm で yarn を入れたあとに確認してみると

user1@pc MINGW64 /c/Program Files (x86)/Nodist/bin
$ ls -1
bin/
etc/
node.exe*
node_modules/
nodist*
nodist.cmd
nodist.ps1
nodist.sh*
nodist_bash_profile_content.sh
npm.cmd
npm.exe*
yarn*
yarn.cmd
yarnpkg*

ここにはパスが通ってるので yarn コマンドは使えます
yarn でパッケージをグローバルインストールしたものはこのフォルダではなくそのさらに内側の bin フォルダにコマンドが配置されます
yarn で parcel をグローバルインストールしてみると

user1@pc MINGW64 /c/Program Files (x86)/Nodist/bin
$ ls bin -1
parcel*
parcel.cmd
parcel.cmd.ps1*
parcel.ps1*
parcel.ps1.cmd
parcel.ps1.ps1*

parcel はパスが通ってないのでそのままでは使えません
「C:\Program Files (x86)\Nodist\bin\bin」 にパスを通せばどこでも yarn でインストールしたツールが使えるようになります
Python のクラスの継承
クラス名のあとのカッコに親クラス名をいれる

class X:
def __init__(self):
self.a = 10

def method():
return 1

class Y(X):
def __init__(self):
self.b = 20

print(vars(Y()))
# {'b': 20}

print(Y().method())
# 1

それだけだと親クラスの初期化処理が行われなくて vars の結果に a が存在しない
初期化されてないだけで継承されてるので method メソッドは使える

他言語で言う super の実行が必要
なくてもエラーはないけど初期化されない

super() は親コンストラクタを表してるわけじゃないので super() で取得できるインスタンスの __init__ メソッド呼び出しが必要

class X:
def __init__(self):
self.a = 10

class Y(X):
def __init__(self):
super().__init__()
self.b = 20

print(vars(Y()))
# {'a': 10, 'b': 20}

子クラスの方で __init__ を書かなければ自動で親クラスが実行される
子クラスで __init__ を定義して初期化するなら 必要あるときだけ親クラスの初期化メソッドを実行できる
実行したくないならしないことができる

class X:
def __init__(self):
self.a = 10

class Y(X):
pass

print(vars(Y()))
# {'a': 10}

実行タイミングも自由に指定できる
self を使う前とか最初じゃなくていい

class X:
def __init__(self):
self.a = 10

class Y(X):
def __init__(self):
self.a = 100
super().__init__()
print(self.a)

Y()
# 10
Liri OS
なんとなく fedora の派生ディストリを眺めたら Hawaii OS というのを発見
なんでハワイ?
ハワイっぽいデザインなのかなと見てみたら

Hawaii is now Liri OS
Hawaii merged with Papyros and is now Liri OS.

http://hawaiios.org/

Liri OS にマージされたみたい
これもはじめて聞いたけど UI のデザインがよさそう
スクリーンショット一覧を見てみてもモダンな感じ
ロゴは折り紙でや名前もわりと好きでちょっと興味あり

Hawaii OS が fedora 派生だったんだからこれも fedora 派生?と思ったのに調べてみると Arch ベースらしい
fedora 以上に新しいのをすぐに取り込む分問題も多いらしいし迷うところ

UI を揃えるために独自にいろいろなソフトウェアも用意してるみたいでリポジトリがいっぱい
https://github.com/lirios
liri ブラウザなんてのもある
VS Code の Python 拡張がメモリ使いすぎ
VS Code の Python 拡張を使うとメモリが使用どんどん増えていく
制限なく増えて 10GB 超え
この辺からは物理メモリに乗らなくなってきて PC の動きが重くなってくるから強制的にプロセス落としてるけど自動で再起動するし しばらくしたらまたメモリが 10GB くらい使ってる
さすがに 10GB 使うのが正常とは思えないし 定義ジャンプ機能使ったらずっとロード中になってるしバグっぽい
バージョンは最新の (2019.1.0) だし しばらくは無効にして使うしかないかなぁ
バイナリファイル中の文字列が半角スペース区切りになってる理由
exe とかのバイナリファイル中でテキストを探すとよく目にするのが半角スペース区切りになってる文字列
"abcd" が "a b c d" という感じ

ビルドしたファイルにローカルのパスが入ってたりしないか探したりするのですが探しづらくて困ります

バイナリファイル中のテキストはそういうふうに入ってるものとなんとなく思ってましたがなんでこんな面倒なことしてるんだろう?
わざわざ検索対策にそんなことするというのは考えにくいです

考えていてひらめいたのが Unicode (UTF-16) だからというもの
バイナリファイル中に見つかる文字はアルファベットばかりで日本語はほぼ見つからないです
あってもちゃんとした意味のある文字列になってないです
UTF-16 ではアルファベットなどは sjis や utf-8 と同じ数値を 0 パディングしたものです
U+0061 が a で U+0041 が A です
1 バイトずつ保存したら 00 と 61 のようになるので エディタで見ると 00 の部分はスペースで 61 の部分が a と表示されて半角スペース区切りというふうに見えると考えられます

試しにエディタで開いてそれぞれの文字コードを見てみると半角スペースは普通の半角スペース (U+0020) ではなく U+0000 になってました
U+0000 は NUL であって半角スペース文字じゃないのでエディタによっては別表示かもしれません

日本語が表示されないのは「あ」は U+3042 ですが 30 と 42 は 0B になってしまうからです
エディタで UTF-16 として開くを実行すれば半角スペースなく表示されますし日本語も表示されます
これで検索しやすくなりました

一応最初にバイナリファイルをエディタで開いたときにエンコーディングをいろいろ試してはいたのですが UTF-16 にすると UTF-8 に比べて文字化けのような変な漢字が大量に出てきて これは違うなと思っていたのですが本当のバイナリデータの部分がそう見えるせいでテキスト部分はちゃんと表示されていました
Python で「,」で終わると
dictionary だったのを個別の変数にコードを修正したときに「,」を消し忘れてたのですが動いてました

こういうの⇩
a = 1,
b = "foo",

Python ってカンマあっても動くんだ
複文みたいな機能があって カンマのあと何もないから何も処理しないってことかな
JavaScript などで ; をいっぱい書いても動くのと同じようなものかな

と思ってたら あっても意味がないというのじゃなく別の意味になってました
カンマで終わるとタプルになります

a
// (1,)
b
// ('foo',)

という感じです
一時的に動かすだけのコードだったのであってもいいならそのままでのつもりだったのですが ちゃんと消さないとダメですね
product ジェネレータ
複数の配列の掛け算的な組み合わせを出力
2 つの配列で 2 重ループで回すようなやつ
任意個数の配列に対応してる
速度求めるなら N 重ループしたほうがいい

function* product(...args) {
if (args.some(e => !Array.isArray(e) || !e.length)) throw new Error("Each argument must be an array.")

function* sub(state, args) {
const [arr, ...subargs] = args

if (!Array.isArray(arr)) {
yield state
return
}

for (const item of arr) {
yield* sub([...state, item], subargs)
}
}
yield* sub([], args)
}

例)
[...product([1, 2], [3, 4], [4], [10, 20, 30])]

// (12) [Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(4)]
// 0: (4) [1, 3, 4, 10]
// 1: (4) [1, 3, 4, 20]
// 2: (4) [1, 3, 4, 30]
// 3: (4) [1, 4, 4, 10]
// 4: (4) [1, 4, 4, 20]
// 5: (4) [1, 4, 4, 30]
// 6: (4) [2, 3, 4, 10]
// 7: (4) [2, 3, 4, 20]
// 8: (4) [2, 3, 4, 30]
// 9: (4) [2, 4, 4, 10]
// 10: (4) [2, 4, 4, 20]
// 11: (4) [2, 4, 4, 30]

for(const [a, b] of product([1, 2], [3, 4])){
console.log(`a = ${a}, b = ${b}`)
}
// a = 1, b = 3
// a = 1, b = 4
// a = 2, b = 3
// a = 2, b = 4
Shift+Enter
Chrome で Google の検索フォームなどのテキスト入力中に Shift-Enter を押すと新しいウィンドウで結果のページが開かれる
タブじゃなくてウィンドウ
URL バーのところでも同じ

Firefox だと URL バーだと新しいタブで開く
URL バーの右側の検索フォームや Google のページなどでは効果なし

Vivaldi だと URL バーの右側の検索フォームや Google のページでは新しいタブで開く
URL バーだと効果なし
PHP も Nginx にしようかなー
https://news.mynavi.jp/article/20181108-720142/

Nginx のシェアが 4 割超えたらしいです
徐々によく見るようになってるなぁ とは思ってましたがここまでとは

Apache って安定してる感はあるけど ほとんど変わらず新しくなにかできるようになったりとかは全然ないですしねー
一応年数回のアップデートはあるようですけど ちょっとした修正だけのようで大きな機能が増えるメジャーアップデートはないです
http://archive.apache.org/dist/httpd/?C=M;O=A
https://www-eu.apache.org/dist//httpd/CHANGES_2.4

それに個人的には Apache 設定ファイルが読みづらくてあんまり好きじゃないです
Apache 使う理由はほぼ PHP が楽に使える点ですけど (静的ファイルのホスティングなら Nginx のほうが得意らしい) それも最近は PHP-FPM という Fast CGI 版が流行りつつあるみたいで これを使うなら Nginx にしても問題なさそうです

Nginx にしてみようかな
hyperHTML だと順番が意味がある
select で option が hyperHTML の機能で生成される場合に value 属性で選択中の値を指定ができないように hyperHTML の ${} は順番に実行される
JavaScript で順に処理されるものなので書く順番で結果が変わる場合もある

bind(document.body)`
<e-lem mode=${"foo"} values=${{x: 1}}>${"bar"}</e-lem>
`

これは

elem.mode = "foo"
elem.values = {x: 1}
elem.textContent= "bar"

と同じこと

HTML みたいな定義型のものに見えるから 順番変えても問題なさそうに見えるけど mode と values の順番が変わると実行順も変わる
values が代入時に mode の値を使って shadowDOM 内を書き換えるのなら 順番によって結果も変わる

コンポーネント側でどんな順番でも同じ結果になるようにしてれば対処は可能
values を内部的に保存しておいて mode 変えると再度 values を設定して shadowDOM 内の更新をするとか

無駄な処理が増えて mode と values 両方変えると更新も 2 回必要になる
けど hyperHTML での定義順に依存したくないならそうするしかない
e-lem コンポーネント自体も hyperHTML で作っていれば setter は常に render して再描画する作りになってることが多いと思うのでそこまで気持ち的に無駄なことしてる感はなくなる
bluebird って ES2015 Promise より速かったんだ
ES2015 になってから結構経つのにまだ bluebird を使った Promise をわりと見かけます
古いものはともかく コードは class 構文をつかうなど ES2015 構文で書かれているにもかかわらずです
標準に比べるとキャンセルとか機能は少し多めですが 標準で組み込まれてる機能があるならそっちのほうがパフォーマンスは優秀だと思いますし Promise は特に内部的に違いがあって JavaScript で完全に再現できないものもあります
Promise.resolve().then() の非同期処理は timeout とはまた少し扱いが違うなどです
標準なものにも 現在の状態 (すでに resolve されているか) がわからないなど不便なところは無いとは言えませんが Promise の仕組み自体を JavaScript で作るよりは標準のものを使ってそれをラップして機能追加するほうが良いように思います

しかし 調べてみたらちょっと意外でした
標準 Promise より bluebird のほうが 高速らしいです
https://softwareengineering.stackexchange.com/questions/278778/why-are-native-es6-promises-slower-and-more-memory-intensive-than-bluebird
bluebird の Promise が ES2015 の仕様に完全準拠してるわけじゃないというのが理由みたいです

ただ それも Node.js 10 でネイティブの Promise が高速化したので bluebird のほうが速いとは限らないようです
もう 10 の LTS が開始しましたし いまから bluebird にしようかと考える必要はないかもしれません
Qrunch よさそう?
Qrunch という新しいサービスが最近できたみたいです
https://qrunch.io/

Qiita と個人ブログの間を目指してるとか
Qiita みたいに「これはふさわしくない」とか言い出す面倒な人がいなさそうで気軽に書けそうですね
アカウントでも作って見よっかと思ったのですが ちょっとした技術メモ書くのがココなわけで いろいろ使い分けると自分でどこに書いたかわからなくなって探すのが大変そう
いまでも一応ブログ 2 つと Gist に別れてるので使ってみたいけど悩みどころ

ところでこのサービスって個人開発みたいですね
作るだけならともかくちゃんと公開して運用・アップデートしていってるのはすごいと思います
私なんてその時の思いつきであれこれ作るものの作ったまま放置で結局自分でも使わず作って満足なものがいっぱい……
ただ使う側からすると急にサービス終わってしまったりとかいう心配もちょっとあったり
使ってみるかもうちょっと考えてみることにします
WebLocks API
https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API
https://developer.mozilla.org/en-US/docs/Web/API/Lock

Web Lock API というのを見つけた

きっかけはこの記事

JavaScriptでデッドロックを作ってみた

Promise で await とかしてるとデッドロックになって先に進まなくなることあるよねーと思って開いてみたら全然違った
こんな機能も実装されたなんて

ちなみにこの記事書いた人ってこのサイトの管理人さんみたい
最近は見てないけど昔 JavaScript 初心者のときにはお世話になったなぁ
懐かしい
見たいページがエラーが起きる
サービスっていうほどでもなくてホームページの延長的なものでそこが提供してる情報の検索ができるみたいなページ
その情報が見たいのになにかエラーで見れないです

ウェブページなので元のソースが github とかにあればこっちで直して見れるのにすごく思います
とは言っても作ってる人は github とは無縁そうな感じのところだし仕方ないけど

ホームページくらいなものでもオープンソースにしておけば見たい人が勝手に直してくれたりしていいんじゃないのって思いました
見れないのも不便なので全部ローカルにコピーして minify されたの読んで動かすかなぁ……

JS 合併とか言うから期待したのに
JS が合併とかいうニュースを見かけて Node.js とブラウザがとうとう?コレは期待!
と思ってたのに

Node.js と JS Foundation

らしいです

JS Foundation?? どこだよそれ
ブラウザ系は ECMA とか whatwg とか W3C とかいろいろ名前あるけど そんな名前はなかったような
調べてみたら jQuery とかライブラリ管理してるところで 元 jQuery Foundation

JS を代表してるかのようなを名前を名乗るほどのところでもないですし Node.js と対等とは思えません
なんか期待に反してどうでもいいような話題でした
input の datetime-local では valueAsDate が使えない
使えるのは date のみ

d: <input type="date">
dtl: <input type="datetime-local">

get
d.value = "2020-01-01"
// "2020-01-01"
d.valueAsDate
// Wed Jan 01 2020 09:00:00 GMT+0900 (日本標準時)
dtl.value = "2020-01-01T00:00:00"
// "2020-01-01T00:00:00"
dtl.valueAsDate
// null

set
d.valueAsDate = new Date()
// Sat Oct 06 2018 20:55:17 GMT+0900 (日本標準時)
d.valueAsDate
// Sat Oct 06 2018 09:00:00 GMT+0900 (日本標準時)
dtl.valueAsDate = new Date()
// Uncaught DOMException: Failed to set the 'valueAsDate' property on 'HTMLInputElement': This input element does not support Date values.

"2020-01-01T00:00:00"
形式しか使えないのも面倒だし対応してほしいなぁ
Chrome が 69 にならない
win7 の PC の Chrome が 68 のままだったからアップデートしようとバージョン画面に行ったら
再起動してくださいってボタンが出てたので押したんだけど
ウィンドウ閉じて一瞬でまたウィンドウが出てきてバージョンは 68 のまま
いったんちゃんと終了してプロセス一覧にないことも確認
そこから起動してもやっぱり 68 のまま
何回やっても一緒だし 69 にならない

ついでにあまり使ってない win10 の PC もやってみたら問題なく 69 になった
……けどデザインが昔のままで 69 からの Firefox っぽいタブにはならなかった
Vivaldi のバージョンが 2 になった
アップデート来てるのを見つけたのでアップデートしてみたらメジャーバージョンアップだったみたいで バージョン 2 になった

とは言っても 見た目は特に変わらないし普段使ってる機能も変わりないみたいで特にいつもどおり
changelog 眺めてみたけどメジャーアップデートっていうほどの大きい変化もない気がする

Chrome バージョンは "Chrome/69.0.3497.102"
Chrome の最新は Chrome/69.0.3497.100 だから微妙にこっちのほうが新しい?
Thunderbird の mintrayr の代替
サンダーバードを常駐化させるためのアドオン MinimizeToTray revived
最小化するとタスクバーから消えてタスクトレイに収まってくれるもの

便利なのに Thunderbird 60 にアップデートすると使えなくなりました
WebExtension に移って既存のが使えなくなってるのが原因みたい

Issue ができていて 読んでみるとフォークして動くようにしてくれてるバージョンがあるみたい
いずれ廃止予定だけど現状で実現できる方法が一応残ってるようです

リポジトリ
アドオン

ここから xpi を落としてインストールすると最小化でタスクトレイに収まるようになりました
ただ アイコンが右クリックできないです
コレに対する Issue はクローズしてるのでアップデートされてないだけかも

それと公式にサポートしてという要望も出てました
https://bugzilla.mozilla.org/show_bug.cgi?id=1486221

完全に WebExtension になるとこの一時的な代替アドオンも動かなくなるし 本来こういう機能はアドオンじゃなく本体がサポートしておくべきだと思うので標準機能になってもらいたいものです
youtube が一時停止する
最近 youtube で作業用 BGM 流してると途中で止まることがある
エラーというわけじゃなく普通に一時停止されてる
全体が暗めになって真ん中にダイアログで一時停止したって書いててボタン押せば再開はできる
だけど BGM だからバックグラウンドのタブだしわざわざ開いて止めるの結構面倒

拡張機能で自動でそのボタン押すことはできそうではあるけど止まってからボタンでるから一瞬音楽が途切れるはず
広告じゃないから広告ブロッカー入れてみても起きた

アフィリエイトとかあるから機械的に再生数稼ぐのを対処するためだと思うけど普通に再生してるユーザに迷惑かけないでほしいな
有名どころ http client をコンプリートしそう
いろいろライブラリを使うものを作ってて http client が各ライブラリごとに別の使ってて有名どころ全部入ってそうな気がしてきた
request, superagent, axios が使われてて 自分で使うものは node-fetch
Webサーバは hapi 使ってるから wreck

http client に限らず同じことするのに別ライブラリがいっぱいあって初回起動に 10 秒近くまたされる
コード変えてももう一回アクセスするだけで更新される PHP ってけっこう便利だったんだなぁって思った
super に渡す関数内で this を使えない
class A {
constructor(){
this.x()
}

x(){}
}

class B extends A {
x(){
console.log(1)
this.value = 1
}
}

new B()

これは問題ないコードです
A のコンストラクタ中で this.x を呼び出して B の x メソッドが呼び出され this.value を更新しています

しかし

class A {
constructor(fn){
fn()
}
}

class B extends A {
constructor(){
super(() => { this.value = 1 })
}
}

new B()

こっちはエラーです
this を使う前に super を呼び出さないといけないというものです
先に super を呼び出して入るものの super の処理が終わる前に 中で this を使う処理を呼び出すとダメみたいです

fn 呼び出しを 「Promise.resolve().then(fn)」 にしてあとで実行させると エラーはでないですが 「new B()」 の時点ではまだ実行されてないのでその後の処理に影響が出ます

super を呼び出していればその中で実行されるものはエラーにしないでほしいです
というか super 呼び出し必須という制限すら不要だと思います
やっぱり class 構文は使わないほうが扱いやすいですね
uws が消された
ちょうど消された頃に知ったのですが忘れてたので short の方に

WebSocket ライブラリの socket.io のソースをみていたら ws という別の WebSocket ライブラリを発見
engine.io が WebSocket のコア部分のライブラリかと思ったら engine.io が中で ws を使ってるみたい

socket.io って結局 ws のラッパー?
よく見ると ws 以外にも uws というのがあって switch 文でどっちを使うか切り替えてる

https://github.com/socketio/engine.io/blob/master/lib/server.js#L108

調べてみたら C++ で書かれた速度重視版で ws と基本的互換性があるとか
npm をみたら deprecated になってた
https://www.npmjs.com/package/uws

見つけたときはちょうどなったばかりで 99.0.0 というバージョンもあって どうなってるんだろう?と思って調べてたらこんなページが

https://www.reddit.com/r/node/comments/91kgte/uws_has_been_deprecated/

Google 翻訳で軽くみた感じでは 作者が npm の考えに賛同できなくてパッケージの公開をやめたみたい
問題のあるバージョンでも消すことができないというのが嫌だったとか
マイナーバージョンアップの 10.148.2 で中身が空のパッケージをリリースしたせいで確認せずアップデートして一部ではトラブルにもなったみたい

使ったこと無いパッケージだったけどこんな事が起きてたんですねー
hapi の inert で 403 エラーになる
confine オプションが true だと relativeTo で設定したフォルダの中しか許可しない
外部だと 403 エラーになる
デフォルトでこのオプションが true

relativeTo は基本的な静的ファイル置き場にして動的に /tmp 以下を返すとかは外部だったのでエラーになって困ってたらこんなところが原因だった
綺麗に出来てるのを複雑にしたくない気持ち
綺麗にできてるツールに機能を追加したいけど綺麗さが崩れてしまうのであんまり直したくない感
最近だと オブジェクトのデータのフォーマットチェックする関数が再帰で return するだけで済んでたのにどこが悪かったのかわからなくてエラー箇所情報などの補足データも入れようとするといろいろごちゃごちゃするし再帰関数外部のデータを保存するところを更新したりとなんだかなぁというコードになった

単純なのだと

value = update(value)



const tmp = update(value)
if (!tmp) return
value = tmp

にするのでも 嫌だなぁって気持ちになる