File size: 7,658 Bytes
927c5e0
b80a08f
927c5e0
b80a08f
 
 
 
 
927c5e0
b80a08f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
927c5e0
b80a08f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
927c5e0
663b536
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Beautify HTML - Versi Gabungan</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.9/beautify-html.min.js"></script>
</head>
<body class="bg-gray-100 min-h-screen flex items-center justify-center p-6 font-sans">

  <div class="w-full max-w-6xl bg-white rounded-xl shadow-xl border border-gray-200">
    <!-- Header -->
    <div class="bg-gradient-to-r from-blue-600 to-blue-500 text-white px-6 py-4 rounded-t-xl">
      <h1 class="text-2xl font-bold">🤖 HTML Beautifier & Cleaner</h1>
      <p class="text-sm opacity-90">Versi gabungan Tailwind + gaya ala BeautifyTools</p>
    </div>

    <!-- Tombol aksi -->
    <div class="p-4 flex flex-wrap gap-3 border-b border-gray-200 bg-gray-50">
      <button onclick="perbaikiHtml()"
              class="px-4 py-2 bg-blue-600 text-white rounded-lg shadow hover:bg-blue-700 transition">
        Perbaiki
      </button>
      <button onclick="beautifyHtml()"
              class="px-4 py-2 bg-purple-600 text-white rounded-lg shadow hover:bg-purple-700 transition">
        Beautify
      </button>
      <button onclick="copyOutput()"
              class="px-4 py-2 bg-green-600 text-white rounded-lg shadow hover:bg-green-700 transition">
        Copy
      </button>
      <button onclick="reviewOutput()"
              class="px-4 py-2 bg-yellow-500 text-white rounded-lg shadow hover:bg-yellow-600 transition">
        Preview
      </button>
      <button onclick="clearInput()"
              class="px-4 py-2 bg-red-600 text-white rounded-lg shadow hover:bg-red-700 transition">
        Clear
      </button>
           
    </div>

    <!-- Tabs -->
    <div class="px-6 pt-4">
      <div class="flex space-x-2 border-b border-gray-200">
        <button id="tab-input" 
                class="tab-btn px-4 py-2 font-medium border-b-2 border-blue-600 text-blue-600 bg-white rounded-t-lg">
          Input
        </button>
        <button id="tab-output" 
                class="tab-btn px-4 py-2 font-medium border-b-2 border-transparent text-gray-600 hover:text-blue-600">
          Hasil Script
        </button>
        <button id="tab-preview" 
                class="tab-btn px-4 py-2 font-medium border-b-2 border-transparent text-gray-600 hover:text-blue-600">
          Live Preview
        </button>
      </div>
    </div>

    <!-- Panels -->
    <div class="p-6">
      <!-- Input -->
      <div id="panel-input" class="tab-panel">
        <textarea id="inputHtml"
                  class="w-full h-72 p-3 border rounded-lg shadow-inner font-mono text-sm focus:ring focus:ring-blue-300"
                  placeholder="<h1>Halo Dunia"></textarea>
      </div>

      <!-- Output -->
      <div id="panel-output" class="tab-panel hidden">
        <textarea id="outputHtml"
                  class="w-full h-96 p-3 border rounded-lg shadow-inner bg-gray-50 font-mono text-sm"
                  readonly></textarea>
      </div>

      <!-- Preview -->
      <div id="panel-preview" class="tab-panel hidden">
        <iframe id="previewFrame" 
                class="w-full h-96 border rounded-lg shadow bg-white"></iframe>
      </div>
    </div>
  </div>

  <script>
    // Tab system
    const tabs = ["input", "output", "preview"];
    function switchTab(name) {
      tabs.forEach(t => {
        const btn = document.getElementById(`tab-${t}`);
        const panel = document.getElementById(`panel-${t}`);
        if (t === name) {
          btn.classList.add("border-blue-600","text-blue-600","bg-white","rounded-t-lg");
          btn.classList.remove("border-transparent","text-gray-600");
          panel.classList.remove("hidden");
        } else {
          btn.classList.remove("border-blue-600","text-blue-600","bg-white","rounded-t-lg");
          btn.classList.add("border-transparent","text-gray-600");
          panel.classList.add("hidden");
        }
      });
    }
    switchTab("input");

    document.getElementById("tab-input").addEventListener("click", () => switchTab("input"));
    document.getElementById("tab-output").addEventListener("click", () => switchTab("output"));
    document.getElementById("tab-preview").addEventListener("click", () => { ensurePreview(); switchTab("preview"); });

    // Logic utama
    function perbaikiHtml() {
      const input = document.getElementById("inputHtml").value.trim();
      const parser = new DOMParser();
      const doc = parser.parseFromString(input || "<!DOCTYPE html><html><head></head><body></body></html>", "text/html");

      let cleaned = "<!DOCTYPE html>\n" + doc.documentElement.outerHTML;

      const needs = [];
      if (!doc.querySelector("meta[charset]")) needs.push("  <meta charset='UTF-8'>");
      if (!doc.querySelector("meta[name='viewport']")) needs.push("  <meta name='viewport' content='width=device-width, initial-scale=1.0'>");
      if (!doc.querySelector("title")) needs.push("  <title>DokumenBaru</title>");
      if (needs.length) cleaned = cleaned.replace("</head>", needs.join("\n") + "\n</head>");

      document.getElementById("outputHtml").value = html_beautify(cleaned, {
        indent_size: 2,
        wrap_line_length: 100,
        preserve_newlines: true
      });
      switchTab("output");
    }

    function beautifyHtml() {
      const output = document.getElementById("outputHtml");
      if (!output.value.trim()) {
        alert("⚠️ Tidak ada hasil untuk Beautify. Klik Perbaiki dulu!");
        return;
      }
      const beautified = html_beautify(output.value, {
        indent_size: 2,
        wrap_line_length: 100,
        preserve_newlines: true
      });
      output.value = beautified;
      switchTab("output");
    }

    function copyOutput() {
      const output = document.getElementById("outputHtml");
      if (!output.value.trim()) {
        alert("⚠️ Tidak ada hasil untuk dicopy. Klik Perbaiki dulu!");
        return;
      }
      navigator.clipboard.writeText(output.value)
        .then(() => alert("✅ Script HTML berhasil dicopy!"))
        .catch(() => {
          output.select();
          document.execCommand("copy");
          alert("✅ Script HTML berhasil dicopy (fallback)!");
        });
    }

    function ensurePreview() {
      const output = document.getElementById("outputHtml").value.trim();
      const iframe = document.getElementById("previewFrame");
      if (output) {
        iframe.srcdoc = output;
      } else {
        const raw = document.getElementById("inputHtml").value.trim();
        iframe.srcdoc = raw || "<h3 style='font-family:sans-serif'>Tidak ada konten untuk dipreview</h3>";
      }
    }

    function reviewOutput() {
      ensurePreview();
      switchTab("preview");
    }

    function clearInput() {
      document.getElementById("inputHtml").value = "";
      document.getElementById("outputHtml").value = "";
      switchTab("input");
    }

    function downloadOutput() {
      const output = document.getElementById("outputHtml").value;
      if (!output.trim()) {
        alert("⚠️ Tidak ada hasil untuk diunduh.");
        return;
      }
      const blob = new Blob([output], { type: "text/html" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = "hasil.html";
      a.click();
      URL.revokeObjectURL(url);
    }

    // Auto focus ke textarea input saat load
    window.onload = () => document.getElementById("inputHtml").focus();
  </script>

</body>
</html>