ignoreDarkModeForBackgroundColorTable()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace App\Docsets;
4
5
use Godbout\DashDocsetBuilder\Docsets\BaseDocset;
6
use Illuminate\Support\Collection;
7
use Illuminate\Support\Facades\Storage;
8
use Illuminate\Support\Str;
9
use Wa72\HtmlPageDom\HtmlPage;
10
use Wa72\HtmlPageDom\HtmlPageCrawler;
11
12
class TailwindCSS extends BaseDocset
13
{
14
    public const CODE = 'tailwindcss';
15
    public const NAME = 'Tailwind CSS';
16
    public const URL = 'tailwindcss.com';
17
    public const INDEX = 'docs/installation/index.html';
18
    public const PLAYGROUND = 'https://codesandbox.io/s/github/lbogdan/tailwindcss-playground';
19
    public const ICON_16 = 'favicon-16x16.png';
20
    public const ICON_32 = 'favicon-32x32.png';
21
    public const EXTERNAL_DOMAINS = [
22
        'refactoring-ui.nyc3.cdn.digitaloceanspaces.com',
23
        'jsdelivr.net',
24
        'code.jquery.com',
25
        'rsms.me',
26
        'googleapis.com',
27
        // 'images.unsplash.com'
28
    ];
29
30 12
    public function entries(string $file): Collection
31
    {
32 12
        $crawler = HtmlPageCrawler::create(Storage::get($file));
33
34 12
        $entries = collect();
35
36 12
        $entries = $entries->merge($this->environmentEntries($crawler, $file));
37 12
        $entries = $entries->merge($this->instructionEntries($crawler, $file));
38 12
        $entries = $entries->merge($this->sampleEntries($crawler, $file));
39 12
        $entries = $entries->merge($this->resourceEntries($crawler, $file));
40 12
        $entries = $entries->merge($this->guideEntries($crawler, $file));
41 12
        $entries = $entries->merge($this->sectionEntries($crawler, $file));
42
43 12
        return $entries;
44
    }
45
46 12
    protected function environmentEntries(HtmlPageCrawler $crawler, string $file)
47
    {
48 12
        $entries = collect();
49
50 12
        if (Str::contains($file, "{$this->url()}/community/index.html")) {
51
            $crawler->filter('h2')->each(function (HtmlPageCrawler $node) use ($entries, $file) {
52 6
                $entries->push([
53 6
                    'name' => $this->cleanAnchorText($node->text()),
54 6
                    'type' => 'Environment',
55 6
                    'path' => Str::after($file . '#' . Str::slug($node->text()), $this->innerDirectory()),
56
                ]);
57 6
            });
58
59 6
            return $entries;
60
        }
61 12
    }
62
63 12
    protected function instructionEntries(HtmlPageCrawler $crawler, string $file)
64
    {
65 12
        $entries = collect();
66
67 12
        if (Str::contains($file, "{$this->url()}/screencasts/index.html")) {
68
            $crawler->filter('span.relative')->each(function (HtmlPageCrawler $node) use ($entries) {
69 6
                $entries->push([
70 6
                    'name' => $this->cleanAnchorText($node->text()),
71 6
                    'type' => 'Instruction',
72 6
                    'path' => $this->url() . '/docs/' . $node->parents()->first()->attr('href'),
73
                ]);
74 6
            });
75
76 6
            return $entries;
77
        }
78 12
    }
79
80 12
    protected function sampleEntries(HtmlPageCrawler $crawler, string $file)
81
    {
82 12
        $entries = collect();
83
84 12
        if (Str::contains($file, "{$this->url()}/components/index.html")) {
85
            $crawler->filter('span.relative')->each(function (HtmlPageCrawler $node) use ($entries) {
86 6
                $entries->push([
87 6
                    'name' => $this->cleanAnchorText($node->text()),
88 6
                    'type' => 'Sample',
89 6
                    'path' => $this->url() . '/components/' . $node->parents()->first()->attr('href'),
90
                ]);
91 6
            });
92
93 6
            return $entries;
94
        }
95 12
    }
96
97 12
    protected function resourceEntries(HtmlPageCrawler $crawler, string $file)
98
    {
99 12
        $entries = collect();
100
101 12
        if (Str::contains($file, "{$this->url()}/resources/index.html")) {
102
            $crawler->filter('h2')->each(function (HtmlPageCrawler $node) use ($entries, $file) {
103 12
                $entries->push([
104 12
                    'name' => $this->cleanAnchorText($node->text()),
105 12
                    'type' => 'Resource',
106 12
                    'path' => Str::after($file . '#' . Str::slug($node->text()), $this->innerDirectory()),
107
                ]);
108 12
            });
109
110
            $crawler->filter('h3')->each(function (HtmlPageCrawler $node) use ($entries, $file) {
111 12
                $entries->push([
112 12
                    'name' => $this->cleanAnchorText($node->text()),
113 12
                    'type' => 'Section',
114 12
                    'path' => Str::after($file . '#' . Str::slug($node->text()), $this->innerDirectory()),
115
                ]);
116 12
            });
117
118 12
            return $entries;
119
        }
120 12
    }
121
122 12
    protected function guideEntries(HtmlPageCrawler $crawler, string $file)
123
    {
124 12
        $pageTitle = (new HtmlPage(Storage::get($file)))->getTitle();
125
126 12
        $entries = collect();
127
128 12
        if ($pageTitle === 'Tailwind CSS - A Utility-First CSS Framework for Rapidly Building Custom Designs') {
129
            $crawler->filter('#navWrapper li a')->each(function (HtmlPageCrawler $node) use ($entries) {
130 6
                $entries->push([
131 6
                    'name' => trim($node->text()),
132 6
                    'type' => 'Guide',
133 6
                    'path' => $this->url() . '/' . $node->attr('href'),
134
                ]);
135 6
            });
136
        }
137
138 12
        return $entries;
139
    }
140
141 12
    protected function sectionEntries(HtmlPageCrawler $crawler, string $file)
142
    {
143 12
        $entries = collect();
144
145
        $crawler->filter('h2')->each(function (HtmlPageCrawler $node) use ($entries, $file) {
146 12
            $entries->push([
147 12
                'name' => $this->cleanAnchorText($node->text()),
148 12
                'type' => 'Section',
149 12
                'path' => Str::after($file . '#' . Str::slug($node->text()), $this->innerDirectory()),
150
            ]);
151 12
        });
152
153 12
        return $entries;
154
    }
155
156 12
    public function format(string $file): string
157
    {
158 12
        $crawler = HtmlPageCrawler::create(Storage::get($file));
159
160 12
        $this->removeNavbarAndHeader($crawler);
161 12
        $this->removeLeftSidebar($crawler);
162 12
        $this->removeRightSidebar($crawler);
163 12
        $this->removeTailwindUIAlert($crawler);
164 12
        $this->removeUnwantedCSS($crawler);
165 12
        $this->removeUnwantedJavaScript($crawler);
166 12
        $this->ignoreDarkModeForSomeColors($crawler);
167 12
        $this->updateCSS($crawler);
168 12
        $this->insertDashTableOfContents($crawler);
169
170 12
        return $crawler->saveHTML();
171
    }
172
173 12
    protected function removeNavbarAndHeader(HtmlPageCrawler $crawler)
174
    {
175 12
        $crawler->filter('body > div:first-child')->remove();
176 12
    }
177
178 12
    protected function removeLeftSidebar(HtmlPageCrawler $crawler)
179
    {
180 12
        $crawler->filter('#sidebar')->remove();
181 12
    }
182
183 12
    protected function removeRightSidebar(HtmlPageCrawler $crawler)
184
    {
185 12
        $crawler->filter('#app div.flex > div.hidden')->remove();
186 12
    }
187
188 12
    protected function removeTailwindUIAlert(HtmlPageCrawler $crawler)
189
    {
190 12
        $crawler->filter('body > div.transition.transform.fixed.z-100')->remove();
191 12
    }
192
193 12
    protected function removeUnwantedCSS(HtmlPageCrawler $crawler)
194
    {
195 12
        $crawler->filter('link[href*="docsearch.min.css"]')->remove();
196 12
    }
197
198 12
    protected function removeUnwantedJavaScript(HtmlPageCrawler $crawler)
199
    {
200 12
        $crawler->filter('script[src*=analytics]')->remove();
201 12
        $crawler->filter('script[src*=docsearch]')->remove();
202 12
        $crawler->filter('script[src*=gtag]')->remove();
203 12
        $crawler->filterXPath("//script[text()[contains(.,'docsearch')]]")->remove();
204 12
        $crawler->filterXPath("//script[text()[contains(.,'gtag')]]")->remove();
205 12
        $crawler->filter('script[src*=jquery]')
206 12
            ->removeAttribute('integrity')
207 12
            ->removeAttribute('crossorigin');
208 12
    }
209
210 12
    protected function ignoreDarkModeForSomeColors(HtmlPageCrawler $crawler)
211
    {
212 12
        $this->ignoreDarkModeForDefaultColorPaletteSection($crawler);
213 12
        $this->ignoreDarkModeForBackgroundColorTable($crawler);
214 12
        $this->ignoreDarkModeForTextColorAndPlaceholderColorTables($crawler);
215 12
        $this->ignoreDarkModeForBorderColorTable($crawler);
216 12
        $this->ignoreDarkModeForDivideColorTable($crawler);
217 12
    }
218
219 12
    protected function ignoreDarkModeForDefaultColorPaletteSection(HtmlPageCrawler $crawler)
220
    {
221 12
        $crawler->filter('h2 ~ div div.w-12')->addClass('dash-ignore-dark-mode');
222 12
    }
223
224 12
    protected function ignoreDarkModeForBackgroundColorTable(HtmlPageCrawler $crawler)
225
    {
226 12
        $crawler->filter('h2 + div td.w-24.p-2.font-mono.text-xs')->addClass('dash-ignore-dark-mode');
227 12
    }
228
229 12
    protected function ignoreDarkModeForTextColorAndPlaceholderColorTables(HtmlPageCrawler $crawler)
230
    {
231 12
        $crawler->filter('h2 + div td.relative.w-16.font-medium.border-t.text-base')->addClass('dash-ignore-dark-mode');
232 12
    }
233
234 12
    protected function ignoreDarkModeForBorderColorTable(HtmlPageCrawler $crawler)
235
    {
236 12
        $crawler->filter('h2 + div td > div.absolute.m-2.border')->addClass('dash-ignore-dark-mode');
237 12
    }
238
239 12
    protected function ignoreDarkModeForDivideColorTable(HtmlPageCrawler $crawler)
240
    {
241 12
        $crawler->filter('h2 + div td > div.absolute.m-2.divide-y')->addClass('dash-ignore-dark-mode');
242 12
    }
243
244 12
    protected function updateCSS(HtmlPageCrawler $crawler)
245
    {
246 12
        $this->updateTopPadding($crawler);
247 12
        $this->updateHeader($crawler);
248 12
        $this->updateContainerWidth($crawler);
249 12
        $this->updateBottomPadding($crawler);
250 12
    }
251
252 12
    protected function updateTopPadding(HtmlPageCrawler $crawler)
253
    {
254 12
        $crawler->filter('#app > div')
255 12
            ->removeClass('pt-12')
256 12
            ->removeClass('pt-24')
257 12
            ->removeClass('pb-16')
258 12
            ->removeClass('lg:pt-28')
259 12
            ->removeClass('lg:pt-12')
260
        ;
261 12
    }
262
263 12
    protected function updateHeader(HtmlPageCrawler $crawler)
264
    {
265 12
        $crawler->filter('#app > div > div.markdown')
266 12
            ->removeClass('lg:ml-0')
267 12
            ->removeClass('lg:mr-auto')
268 12
            ->removeClass('xl:mx-0')
269 12
            ->removeClass('xl:w-3/4')
270 12
            ->removeClass('max-w-3xl')
271 12
            ->removeClass('xl:px-12')
272
        ;
273 12
    }
274
275 12
    protected function updateContainerWidth(HtmlPageCrawler $crawler)
276
    {
277 12
        $crawler->filter('body > div:first-child')
278 12
            ->removeClass('max-w-screen-xl');
279
280 12
        $crawler->filter('#content-wrapper')
281 12
            ->removeClass('lg:static')
282 12
            ->removeClass('lg:max-h-full')
283 12
            ->removeClass('lg:overflow-visible')
284 12
            ->removeClass('lg:w-3/4')
285 12
            ->removeClass('xl:w-4/5');
286
287 12
        $crawler->filter('#app > div > div.flex > div.markdown')
288 12
            ->removeClass('xl:p-12')
289 12
            ->removeClass('max-w-3xl')
290 12
            ->removeClass('lg:ml-0')
291 12
            ->removeClass('lg:mr-auto')
292 12
            ->removeClass('xl:w-3/4')
293 12
            ->removeClass('xl:px-12')
294 12
            ->removeClass('xl:mx-0');
295 12
    }
296
297 12
    protected function updateBottomPadding(HtmlPageCrawler $crawler)
298
    {
299 12
        $crawler->filter('body')
300 12
            ->addClass('pb-8');
301 12
    }
302
303 12
    protected function insertDashTableOfContents(HtmlPageCrawler $crawler)
304
    {
305 12
        $crawler->filter('h1')
306 12
            ->before('<a name="//apple_ref/cpp/Section/Top" class="dashAnchor"></a>');
307
308
        $crawler->filter('h2, h3')->each(function (HtmlPageCrawler $node) {
309 12
            $node->prepend(
310 12
                '<a id="' . Str::slug($node->text()) . '" name="//apple_ref/cpp/Section/' . rawurlencode($this->cleanAnchorText($node->text())) . '" class="dashAnchor"></a>'
311
            );
312 12
        });
313 12
    }
314
315 18
    protected function cleanAnchorText($anchorText)
316
    {
317 18
        return trim(preg_replace('/\s+/', ' ', $anchorText));
318
    }
319
}
320