Przeglądaj źródła

Refactor template loading

Thomas Dy 6 lat temu
rodzic
commit
898b4e12d2
6 zmienionych plików z 115 dodań i 131 usunięć
  1. 84 84
      dist/index.html
  2. 1 1
      src/editor.ts
  3. 2 0
      src/game.ts
  4. 1 0
      src/game/common.ts
  5. 7 16
      src/game/select.ts
  6. 20 30
      src/util.ts

+ 84 - 84
dist/index.html

@@ -8,99 +8,99 @@
     <div id="container" class="loading">
       <div id="background"></div>
       <div id="loading">Loading...</div>
-    </div>
-    <template id="base-template">
-      <div id="folder-info">
-        <i class="left material-icons">chevron_left</i>
-        <i class="material-icons">album</i>
-        <i class="right material-icons">chevron_right</i>
-        <span class="label"></span>
-      </div>
-      <div id="song-info"></div>
-      <div id="song-list"></div>
-      <div id="game">
-        <div class="track-progress">
-          <span class="total-label">Total Time</span>
-          <span class="interval-label">Interval</span>
-          <template class="total" name="progress-bar"></template>
-          <template class="interval" name="progress-bar"></template>
+
+      <template id="base-template">
+        <div id="folder-info">
+          <i class="left material-icons">chevron_left</i>
+          <i class="material-icons">album</i>
+          <i class="right material-icons">chevron_right</i>
+          <span class="label"></span>
         </div>
-        <div class="score-line">
-          <span class="combo"></span>
-          <div class="pair">
-            <span class="label">Score</span>
-            <span class="value score"></span>
-          </div>
-          <div class="pair">
-            <span class="label">Max Combo</span>
-            <span class="value max-combo"></span>
-          </div>
-          <div class="pair">
-            <span class="label">Finished</span>
-            <span class="value finished"></span>
+        <div id="song-info">
+          <div class="song-info">
+            <div class="genre"></div>
+            <div class="creator"></div>
+            <div class="title"></div>
           </div>
         </div>
-        <div class="kana-line"></div>
-        <div class="kanji-line"></div>
-        <div class="romaji-first"></div>
-        <div class="romaji-line"></div>
-        <div class="stats-line">
-          <div class="pair">
-            <span class="label">Hit</span>
-            <span class="value hit"></span>
+        <div id="song-list"></div>
+        <div id="game">
+          <div class="track-progress">
+            <span class="total-label">Total Time</span>
+            <span class="interval-label">Interval</span>
+            <template class="total" name="progress-bar"></template>
+            <template class="interval" name="progress-bar"></template>
           </div>
-          <div class="pair">
-            <span class="label">Missed</span>
-            <span class="value missed"></span>
+          <div class="score-line">
+            <span class="combo"></span>
+            <div class="pair">
+              <span class="label">Score</span>
+              <span class="value score"></span>
+            </div>
+            <div class="pair">
+              <span class="label">Max Combo</span>
+              <span class="value max-combo"></span>
+            </div>
+            <div class="pair">
+              <span class="label">Finished</span>
+              <span class="value finished"></span>
+            </div>
           </div>
-          <div class="pair">
-            <span class="label">Skipped</span>
-            <span class="value skipped"></span>
+          <div class="kana-line"></div>
+          <div class="kanji-line"></div>
+          <div class="romaji-first"></div>
+          <div class="romaji-line"></div>
+          <div class="stats-line">
+            <div class="pair">
+              <span class="label">Hit</span>
+              <span class="value hit"></span>
+            </div>
+            <div class="pair">
+              <span class="label">Missed</span>
+              <span class="value missed"></span>
+            </div>
+            <div class="pair">
+              <span class="label">Skipped</span>
+              <span class="value skipped"></span>
+            </div>
           </div>
         </div>
-      </div>
-      <div id="score">
-        <span>Score</span><div class="score"></div>
-        <span>Max Combo</span><div class="max-combo"></div>
-        <span>Finished</span><div class="finished"></div>
-        <span>Hit</span><div class="hit"></div>
-        <span>Missed</span><div class="missed"></div>
-        <span>Skipped</span><div class="skipped"></div>
-      </div>
-      <div id="loader">
-        <template name="progress-bar"></template>
-        <span class="label"></span>
-      </div>
-      <div id="ready">
-        <div class="status"></div>
-        <div class="message"></div>
-      </div>
-    </template>
-    <template id="song-info-template">
-      <div class="song-info">
-        <div class="genre"></div>
-        <div class="creator"></div>
-        <div class="title"></div>
-      </div>
-    </template>
-    <template id="song-item-template">
-      <div class="song-item">
-        <div class="difficulty-bg normal"></div>
-        <div class="difficulty-bg"></div>
-        <div class="difficulty"></div>
-        <div class="creator"></div>
-        <div class="title"></div>
-      </div>
-    </template>
-    <template id="progress-bar-template">
-      <div class="progress-bar">
-        <div class="bg"></div>
-        <div class="shade"></div>
-      </div>
-    </template>
+        <div id="score">
+          <span>Score</span><div class="score"></div>
+          <span>Max Combo</span><div class="max-combo"></div>
+          <span>Finished</span><div class="finished"></div>
+          <span>Hit</span><div class="hit"></div>
+          <span>Missed</span><div class="missed"></div>
+          <span>Skipped</span><div class="skipped"></div>
+        </div>
+        <div id="loader">
+          <template name="progress-bar"></template>
+          <span class="label"></span>
+        </div>
+        <div id="ready">
+          <div class="status"></div>
+          <div class="message"></div>
+        </div>
+
+        <template id="song-item-template">
+          <div class="song-item">
+            <div class="difficulty-bg normal"></div>
+            <div class="difficulty-bg"></div>
+            <div class="difficulty"></div>
+            <div class="creator"></div>
+            <div class="title"></div>
+          </div>
+        </template>
+        <template id="progress-bar-template">
+          <div class="progress-bar">
+            <div class="bg"></div>
+            <div class="shade"></div>
+          </div>
+        </template>
+      </template>
+    </div>
     <script type="text/javascript" src="bundle.js"></script>
     <script type="text/javascript">
-      util.loadBase();
       new game.MainController(
         document.querySelector('#container'),
         'levels.json'

+ 1 - 1
src/editor.ts

@@ -232,7 +232,7 @@ namespace editor {
       this.markerElement = document.createElement('div');
       this.markerElement.className = 'marker';
 
-      let fragment = util.loadTemplate('interval');
+      let fragment = util.loadTemplate(document, 'interval');
       this.liElement = util.getElement(fragment, '*');
       this.inputElement = util.getElement(fragment, '.interval');
       this.inputElement.addEventListener('change', () => {

+ 2 - 0
src/game.ts

@@ -10,6 +10,7 @@ namespace game {
 
     constructor(container: HTMLElement, configUrl: string) {
       super(container);
+      container.appendChild(util.loadTemplate(container, 'base'));
 
       let self = this;
       let bgLayer: HTMLElement = util.getElement(container, '#background');
@@ -17,6 +18,7 @@ namespace game {
         container: container,
         audioManager: new audio.AudioManager(),
         bgManager: new background.BackgroundManager(bgLayer),
+        loadTemplate: (id: string) => util.loadTemplate(container, id),
         assets: null,
         config: null,
         switchScreen(screen: Screen): void {

+ 1 - 0
src/game/common.ts

@@ -59,6 +59,7 @@ namespace game {
     container: HTMLElement;
     audioManager: audio.AudioManager;
     bgManager: background.BackgroundManager;
+    loadTemplate: (id: string) => DocumentFragment;
     assets: GameSounds | null;
     config: level.Config | null;
 

+ 7 - 16
src/game/select.ts

@@ -35,6 +35,7 @@ namespace game {
       this.listControllers = [];
       this.levelSets.forEach(levelSet => {
         let controller = new SongListController(
+          this.context,
           levelSet.levels,
           (index) => this.selectSong(index),
           (index) => this.chooseSong(index)
@@ -68,10 +69,10 @@ namespace game {
       if (!this.init && selectSound !== null) {
         selectSound.play();
       }
-      let song = this.currentLevelSet.levels[index];
-      let songInfoComponent = new SongInfoComponent(song);
-      util.clearChildren(this.songInfo);
-      this.songInfo.appendChild(songInfoComponent.element);
+      let level = this.currentLevelSet.levels[index];
+      this.songInfo.querySelector('.genre')!.textContent = level.genre;
+      this.songInfo.querySelector('.creator')!.textContent = level.creator;
+      this.songInfo.querySelector('.title')!.textContent = level.name;
     }
 
     chooseSong(index: number): void {
@@ -144,17 +145,6 @@ namespace game {
     }
   }
 
-  class SongInfoComponent {
-    element: DocumentFragment;
-
-    constructor(level: level.Level) {
-      this.element = util.loadTemplate('song-info');
-      this.element.querySelector('.genre')!.textContent = level.genre;
-      this.element.querySelector('.creator')!.textContent = level.creator;
-      this.element.querySelector('.title')!.textContent = level.name;
-    }
-  }
-
   class SongListController {
     element: HTMLElement;
     levels: level.Level[];
@@ -163,6 +153,7 @@ namespace game {
     onSongChoose: (index: number) => void;
 
     constructor(
+      context: GameContext,
       levels: level.Level[],
       onSongChange: (index: number) => void,
       onSongChoose: (index: number) => void
@@ -177,7 +168,7 @@ namespace game {
       this.element.style.marginTop = '12.5em';
 
       this.levels.forEach((level, index) => {
-        let element = util.loadTemplate('song-item');
+        let element = context.loadTemplate('song-item');
         element.querySelector('.creator')!.textContent = level.creator;
         element.querySelector('.title')!.textContent = level.name;
         element.querySelector('.difficulty')!.textContent = level.difficulty;

+ 20 - 30
src/util.ts

@@ -1,35 +1,25 @@
 namespace util {
-  export function loadBase(): void {
-    let container = document.querySelector('#container');
-    if (container === null) {
-      throw new Error('Container not found');
-    }
-
-    let baseTemplate = loadTemplate('base');
-    baseTemplate.querySelectorAll('template').forEach(t => {
-      let parent = t.parentNode as Node;
-      const templateName = t.getAttribute('name');
-      if (templateName === null) {
-        return;
-      }
-      let template = loadTemplate(templateName);
-      let firstElement = template.querySelector('*');
-      if (firstElement !== null) {
-        for (let i = 0; i < t.classList.length; ++i) {
-          firstElement.classList.add(t.classList[i]);
-        }
-      }
-      parent.insertBefore(template, t);
-      parent.removeChild(t);
-    });
-
-    container.appendChild(baseTemplate);
-  }
-
-  export function loadTemplate(id: string): DocumentFragment {
-    let template = document.querySelector(`#${id}-template`);
+  export function loadTemplate(element: ParentNode, id: string): DocumentFragment {
+    let template = element.querySelector(`#${id}-template`);
     if (template !== null && template instanceof HTMLTemplateElement) {
-      return document.importNode(template.content, true);
+      const fragment = document.importNode(template.content, true);
+      fragment.querySelectorAll('template').forEach(t => {
+        let parent = t.parentNode!;
+        const templateName = t.getAttribute('name');
+        if (templateName === null) {
+          return;
+        }
+        let template = loadTemplate(fragment, templateName);
+        let firstElement = template.querySelector('*');
+        if (firstElement !== null) {
+          for (let i = 0; i < t.classList.length; ++i) {
+            firstElement.classList.add(t.classList[i]);
+          }
+        }
+        parent.insertBefore(template, t);
+        parent.removeChild(t);
+      });
+      return fragment;
     } else {
       throw new Error(`#${id}-template is not a template`);
     }