Completed
Branch master (446cf6)
by Guillaume
04:16 queued 01:26
created

TailwindCSS   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 222
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 19
eloc 117
dl 0
loc 222
c 0
b 0
f 0
rs 10

16 Methods

Rating   Name   Duplication   Size   Complexity  
A resourceEntries() 0 22 2
A insertDashTableOfContents() 0 8 1
A removeLeftSidebar() 0 3 1
A updateBottomPadding() 0 4 1
A updateHeader() 0 9 1
A updateTopPadding() 0 8 1
A sectionEntries() 0 15 1
A updateCSS() 0 6 1
A removeRightSidebar() 0 3 1
A sampleEntries() 0 29 2
A removeNavbarAndHeader() 0 3 1
A updateContainerWidth() 0 20 1
A cleanAnchorText() 0 3 1
A entries() 0 12 1
A guideEntries() 0 17 2
A format() 0 11 1
1
<?php
2
3
namespace App\Docsets;
4
5
use Illuminate\Support\Str;
6
use Wa72\HtmlPageDom\HtmlPage;
7
use Illuminate\Support\Collection;
8
use Wa72\HtmlPageDom\HtmlPageCrawler;
9
use Illuminate\Support\Facades\Storage;
10
11
class TailwindCSS extends BaseDocset
12
{
13
    public const CODE = 'tailwindcss';
14
    public const NAME = 'Tailwind CSS';
15
    public const URL = 'tailwindcss.com';
16
    public const INDEX = 'installation.html';
17
    public const PLAYGROUND = 'https://codesandbox.io/s/github/lbogdan/tailwindcss-playground';
18
    public const ICON_16 = 'favicon-16x16.png';
19
    public const ICON_32 = 'favicon-32x32.png';
20
    public const EXTERNAL_DOMAINS = [
21
        'refactoring-ui.nyc3.cdn.digitaloceanspaces.com'
22
    ];
23
24
    public function entries(string $file): Collection
25
    {
26
        $crawler = HtmlPageCrawler::create(Storage::get($file));
27
28
        $entries = collect();
29
30
        $entries = $entries->merge($this->sampleEntries($crawler, $file));
31
        $entries = $entries->merge($this->resourceEntries($crawler, $file));
32
        $entries = $entries->merge($this->guideEntries($crawler, $file));
33
        $entries = $entries->merge($this->sectionEntries($crawler, $file));
34
35
        return $entries;
36
    }
37
38
    protected function sampleEntries(HtmlPageCrawler $crawler, string $file)
39
    {
40
        $entries = collect();
41
42
        if (in_array(basename($file), [
43
            'alerts.html',
44
            'buttons.html',
45
            'cards.html',
46
            'forms.html',
47
            'grids.html',
48
            'navigation.html'
49
        ])) {
50
            $parent = $crawler->filter('h1')->first();
51
52
            $entries->push([
53
                'name' => $this->cleanAnchorText($parent->text()),
54
                'type' => 'Sample',
55
                'path' => basename($file) . '#' . Str::slug($parent->text()),
56
            ]);
57
58
            $crawler->filter('h2')->each(function (HtmlPageCrawler $node) use ($entries, $file, $parent) {
59
                $entries->push([
60
                    'name' => $this->cleanAnchorText($node->text()) . ' - ' . $parent->text(),
61
                    'type' => 'Sample',
62
                    'path' => basename($file) . '#' . Str::slug($node->text()),
63
                ]);
64
            });
65
66
            return $entries;
67
        }
68
    }
69
70
    protected function resourceEntries(HtmlPageCrawler $crawler, string $file)
71
    {
72
        $entries = collect();
73
74
        if (basename($file) === 'resources.html') {
75
            $parent = $crawler->filter('h1')->first();
76
77
            $entries->push([
78
                'name' => $this->cleanAnchorText($parent->text()),
79
                'type' => 'Resource',
80
                'path' => basename($file) . '#' . Str::slug($parent->text()),
81
            ]);
82
83
            $crawler->filter('h2')->each(function (HtmlPageCrawler $node) use ($entries, $file, $parent) {
84
                $entries->push([
85
                    'name' => $this->cleanAnchorText($node->text()) . ' - ' . $parent->text(),
86
                    'type' => 'Resource',
87
                    'path' => basename($file) . '#' . Str::slug($node->text()),
88
                ]);
89
            });
90
91
            return $entries;
92
        }
93
    }
94
95
    protected function guideEntries(HtmlPageCrawler $crawler, string $file)
96
    {
97
        $pageTitle = (new HtmlPage(Storage::get($file)))->getTitle();
98
99
        $entries = collect();
100
101
        if ($pageTitle === 'Installation - Tailwind CSS') {
102
            $crawler->filter('#navWrapper li a')->each(static function (HtmlPageCrawler $node) use ($entries) {
103
                $entries->push([
104
                    'name' => trim($node->text()),
105
                    'type' => 'Guide',
106
                    'path' => $node->attr('href'),
107
                ]);
108
            });
109
        }
110
111
        return $entries;
112
    }
113
114
    protected function sectionEntries(HtmlPageCrawler $crawler, string $file)
115
    {
116
        $entries = collect();
117
118
        $parent = $crawler->filter('h1')->first();
119
120
        $crawler->filter('h2')->each(function (HtmlPageCrawler $node) use ($entries, $file, $parent) {
121
            $entries->push([
122
                'name' => $this->cleanAnchorText($node->text()) . ' - ' . $parent->text(),
123
                'type' => 'Section',
124
                'path' => basename($file) . '#' . Str::slug($node->text()),
125
            ]);
126
        });
127
128
        return $entries;
129
    }
130
131
    public function format(string $html): string
132
    {
133
        $crawler = HtmlPageCrawler::create($html);
134
135
        $this->removeNavbarAndHeader($crawler);
136
        $this->removeLeftSidebar($crawler);
137
        $this->removeRightSidebar($crawler);
138
        $this->updateCSS($crawler);
139
        $this->insertDashTableOfContents($crawler);
140
141
        return $crawler->saveHTML();
142
    }
143
144
    protected function removeNavbarAndHeader(HtmlPageCrawler $crawler)
145
    {
146
        $crawler->filter('body > div:first-child')->remove();
147
    }
148
149
    protected function removeLeftSidebar(HtmlPageCrawler $crawler)
150
    {
151
        $crawler->filter('#sidebar')->remove();
152
    }
153
154
    protected function removeRightSidebar(HtmlPageCrawler $crawler)
155
    {
156
        $crawler->filter('#app div.flex > div.hidden')->remove();
157
    }
158
159
    protected function updateCSS(HtmlPageCrawler $crawler)
160
    {
161
        $this->updateTopPadding($crawler);
162
        $this->updateHeader($crawler);
163
        $this->updateContainerWidth($crawler);
164
        $this->updateBottomPadding($crawler);
165
    }
166
167
    protected function updateTopPadding(HtmlPageCrawler $crawler)
168
    {
169
        $crawler->filter('#app > div')
170
            ->removeClass('pt-12')
171
            ->removeClass('pt-24')
172
            ->removeClass('pb-16')
173
            ->removeClass('lg:pt-28')
174
            ->removeClass('lg:pt-12')
175
        ;
176
    }
177
178
    protected function updateHeader(HtmlPageCrawler $crawler)
179
    {
180
        $crawler->filter('#app > div > div.markdown')
181
            ->removeClass('lg:ml-0')
182
            ->removeClass('lg:mr-auto')
183
            ->removeClass('xl:mx-0')
184
            ->removeClass('xl:w-3/4')
185
            ->removeClass('max-w-3xl')
186
            ->removeClass('xl:px-12')
187
        ;
188
    }
189
190
    protected function updateContainerWidth(HtmlPageCrawler $crawler)
191
    {
192
        $crawler->filter('body > div:first-child')
193
            ->removeClass('max-w-screen-xl');
194
195
        $crawler->filter('#content-wrapper')
196
            ->removeClass('lg:static')
197
            ->removeClass('lg:max-h-full')
198
            ->removeClass('lg:overflow-visible')
199
            ->removeClass('lg:w-3/4')
200
            ->removeClass('xl:w-4/5');
201
202
        $crawler->filter('#app > div > div.flex > div.markdown')
203
            ->removeClass('xl:p-12')
204
            ->removeClass('max-w-3xl')
205
            ->removeClass('lg:ml-0')
206
            ->removeClass('lg:mr-auto')
207
            ->removeClass('xl:w-3/4')
208
            ->removeClass('xl:px-12')
209
            ->removeClass('xl:mx-0');
210
    }
211
212
    protected function updateBottomPadding(HtmlPageCrawler $crawler)
213
    {
214
        $crawler->filter('body')
215
            ->addClass('pb-8');
216
    }
217
218
    protected function insertDashTableOfContents(HtmlPageCrawler $crawler)
219
    {
220
        $crawler->filter('h1')
221
            ->before('<a name="//apple_ref/cpp/Section/Top" class="dashAnchor"></a>');
222
223
        $crawler->filter('h2, h3')->each(function (HtmlPageCrawler $node) {
224
            $node->prepend(
225
                '<a id="' . Str::slug($node->text()) . '" name="//apple_ref/cpp/Section/' . rawurlencode($this->cleanAnchorText($node->text())) . '" class="dashAnchor"></a>'
226
            );
227
        });
228
    }
229
230
    protected function cleanAnchorText($anchorText)
231
    {
232
        return trim(preg_replace('/\s+/', ' ', $anchorText));
233
    }
234
}
235