Flutter備忘録: DartPadでブログ内にFlutter/Dartコードをページ幅で表示する方法

Flutter備忘録 Logo

最近、FlutterのAPIドキュメントを良く眺めていますが、ドキュメントのページ内に含まれるサンプルコードの一部はブラウザ上で実際に実行して結果を確認出来る仕様になっています。

例: AnimatedListFutureBuilderPhysicalShape クラスなど

少し気になったので仕組みを検索した処、Webページのソースに『DartPad』というJavaScriptで書かれたオープンソースのスクリプトを組み込む事でFlutter/Dartで書かれた任意のコードがブラウザ上で実行可能になるそうです。

このサイトで、これまでに、いくつかのFluterコードを含む備忘録をメモしているので、今後のメモに使えるのではと思い、『DartPad』を使ってみました。


DartPadのWikiの組み込みガイドにはGitHubのgistを表示する方法(①)と、タグ内にコードを埋め込む方法(②)の2つが紹介されていますが、この備忘録では後者の②を使った方法を簡単に紹介しています。


悲報: ②サポート終了

②の方法はページが比較的重くなるという理由で廃止になった様です。

組み込みに使うスクリプト「inject_embed.dart.js」が削除されているので、以前②の方法でDartPadを表示していた場合は読み込みエラーになるのでDartPadは表示されなくなっています。


でも、上記のガイドの通りにするだけだと、実際にページ内に表示されるDartPadの幅が300px程度しかなく、小さすぎて使い物になりませんでした。 そこで、CSSやJSを使って修正を加えたらDartPadをページ幅で表示が出来たので、解決方法もこの記事で紹介しています。


DartPad組み込みガイド

DartPadのWikiに「Embedding Guide (組み込みガイド)」があったので参考にしましたが、任意のコードをDartPadで表示するのには:

  1. GitHubにコードをgistとしてアップロードした後、そのgistのIDを参照してDartPadを表示するURLをiframeタグとして表示する。
  2. DartPad表示用のJavaScript(inject_embed.dart.js)をscriptタグで読み込んで、DartPadで表示したいコードの部分(code block)を特定のクラス指定をしたcodeタグで囲んでページ内に置く。

という方法の2つがガイドに掲載されていました。 (検索すると同ページの内容を日本語で書き直しただけのページが多数出てくると思うのでガイドの詳細はここでは省略しておきます。)


ブログ記事に載せる事を前提に考えると、①の方法は、表示させたいコードはブログサイトとは別の場所のGitHubにアップロードする為、2か所での編集/管理が必要になります。 一方、②の方法だと、ブログサイト1か所だけでの編集で済みます。

又、細かい事を言うと、可能性は少ないと思いますが、GitHubへのアクセスに何らかの障害があった場合、①の方法だとiframeタグ内のコードが全く表示されないという結果になります。 ②の方法でも、DartPad表示用のJavaScriptがGitHubから読み込まれる為、GitHubのサイトへのアクセスに問題があった場合にはDartPadは表示されなくなりますが、codeタグの内容はDartPad無しでそのままテキストとして表示されます。

たぶん、GitHubを日常的に使っていたら余り気にならない点なのかもしれませんが、個人的にはGitHubのアカウントは持ってはいますが最近作ったばかりでまだ初心者なので①ではなく②の方法を試してみました…


Converting code blocks to DartPad (コードブロックをDartPadに変換)

組み込みガイドには②の方法には、例としてお決まりの「Hello World」が紹介されています:

<script type="text/javascript" src="https://dartpad.dev/inject_embed.dart.js" defer></script>

<pre>
<code class="language-run-dartpad:theme-light:mode-flutter:ga_id-example1">
main() => print("Hello, World!");
</code>
</pre>
(ガイドのConverting code blocks to DartPadより引用)

[Solved] 何故か小さく表示されて使い物にならないDartPad...

👇とりあえず上記の方法でこのページに組み込んでみましたが。。。

  main() => print("Hello, World!");

の仕様では、何故かページ幅よりも全然小さい大きさ (ほぼ300x150) で表示されてしまうみたいです。

これだと全く使い物になりません。。。   なので以降に解決方をメモしておきます。


タグにスタイルを指定してみる

①の方法のガイドにはiframeタグにスタイル(style)属性を追加して、幅(width)と高さ(height)を指定出来るとあったので、同様の設定が②の方法にも使えるかと思い、次の様なスタイル属性をcodeタグを囲むpreタグに追加してみました。

<pre style="width: 100%; height: 300px;">

でも、表示されるDartPadの大きさは変わらず、実際に表示されたページのソースを確認した処、codeタグとそれを囲むpreタグが、JavaScriptが実行された後にはdivタグに囲まれたiframeタグに置き換えられていました…。

<pre>
  <code class="language-run-dartpad:...">
    :    :    :
  </code>
</pre>
 ⇒ 
<div>
  <iframe src="https://dartpad.dev/embed-flutter.html?theme=..." ... ></iframe>
</div>

つまり、preタグやcodeタグに設定を加えても上書きされてしまう為、無効になってしまいます。


解決方

解決方1: CSSでiframeのスタイルを変更してページ幅に

次の様なCSSを追加すればiframeの大きさを変更する事は可能ですが:

iframe {
  width: 100%;
  height: 100%;
}

DartPadのJavaScriptで書き換えられたiframeタグはdivタグで囲われている上に、このdivとiframeには特有なクラス名が設定されていません。


なので、次の様にpreとcodeのタグの部分を特有なclass名を指定したdivタグで囲えば、このクラス名を使って下にくるdiviとframeにスタイルを適用する事が出来ます。

<div class="example-css" style="margin: 10px auto; width: 95%; height:120px;">
<pre>
<code class="language-run-dartpad:theme-light:mode-flutter:ga_id-example2"> main() => print("Hello, World!");
</code>
</pre> </div>

これに次のCSS設定を加える事でDartPadを表示するiframeの大きさが上で加えたdivタグの大きさで表示されます。

example-css>div, .example-css iframe {
  width: 100%;
  height: 100%;
}

👇実際に上記の設定を追加したDartPadを次に:

  main() => print("Hello, World!");

これでDartPadをページ幅で表示する事が出来ました。


解決方2: JavaScriptでスタイルを変更してページ幅に

次にCSSではなくJavaScriptを使った方法を。

次の様に特有のクラス名を指定したdivタグで囲みます。(次の例では「example-js」というクラス名を指定してあります。)

<div class="example-js" style="margin: 10px auto; width: 95%">
<pre><code class="language-run-dartpad:theme-light:mode-flutter:ga_id-example3">
main() => print("Hello, World!");
</code>
</pre>
</div>

次のJavaScriptはページ内の「example-js」を見つけて、そのタグ中にあるiframeタグのスタイルを変更します。

window.addEventListener('load', function() {
  const item = document.getElementById("example-js");
  const div = item.children[0];
  div.style.width="100%";
  div.style.height="100%";
  const frame = item.getElementsByTagName("iframe")[0];
  frame.style.width="100%";
  frame.style.height="100%";
});

👇実際に上記の設定を追加したDartPadを次に:

  main() => print("Hello, World!");

将来的にはDartPadの仕様が変更されてこの様な設定を追加しなくても良くなるかもしれませんが、DartPadを使ってFlutter/Dartコードをページ幅で表示する事が出来ました。



コメント

このブログの人気の投稿

[OBS] Twitchコメント欄向けCSSカスタマイザー (試作)

『コメ欄』用カスタムCSS - L◯NE風 (ツイキャス) - OBSのブラウザでも使えます。

[ツイキャス配信・閲覧支援ツール] キャスポケットツール: 初期設定

ツイキャスで他の人がサポートしている人って見えますか? (キャスポケットツール)

[OBS] コメントを逆の順番で表示 (ツイキャス/YouTube)

ツイキャス専門 『コメ欄』Lite (ライト)と『コメ欄』✚ (プラス)

キャスポケットツール: 検索の巻 (ツイキャスのユーザー検索とライブ検索)

最近のプロジェクト (Pololu社 SMC: DCモーター制御ボード)