css.pl
370 lines of code
1
#!/usr/bin/perl
2
3
        # may have had an epiphany last night.  maybe, maybe,
4
        # my "centering" div CSS class needs auto scrolling
5
        # enabled? cuz, if the content of the div gets way
6
        # large, the div overflows its container instead of
7
        # stretching its container! like...wtf? or does the
8
        # div's container require auto scrolling?
9
10
use strict;
11
use warnings;
12
use CGI qw(:standard);
13
use CGI::Carp qw(fatalsToBrowser);
14
use CSS::Sass;
15
16
use lib "./Pm";
17
18
use Bc_chef qw(cookie_get);
19
use Bc_misc qw(get_param referrer clear_spaces hexDigit2Dec new_id);
20
use Bc_sql qw(get_constant
21
              sql_execute
22
              user_exists
23
              theme_exists
24
              get_theme_data
25
              get_default_theme
26
27
              $DB
28
              $QUERY_PAGE
29
              $QUERY_UID
30
              $LOGGEDIN
31
              $curr_db_fn
32
             );
33
34
use User qw(
35
            get_user_stats
36
            isUserAdmin
37
            isUserBeta
38
            get_user_theme_data
39
40
            $USER_DATA
41
            $THEME_DATA
42
           );
43
44
use Html qw(pre_html_header);
45
use Bc_dir qw(
46
              read_text
47
              file_exists
48
             );
49
50
use Security;
51
52
# we connect to this db because that's where our theme data is stored
53
$DB = Bc_sql::sql_connect("./2812.ns.db");
54
55
my %headerCfg;
56
$headerCfg{type} = "text/css";
57
$headerCfg{status} = "200 Ok";
58
59
my $DEBUG = 0;
60
61
##########################################
62
my $output = "";
63
64
my $nobg = get_param("nobg_img");
65
my $nogrid = get_param("nogrid");
66
my $override_theme = get_param("tid");
67
if ($override_theme) {
68
  $THEME_DATA = Bc_sql::get_theme_data($override_theme);
69
} else {
70
  $THEME_DATA = Bc_sql::get_theme_data(User::get_user_theme())
71
}
72
73
if ($DEBUG) {
74
  $output .= "/*\n";
75
  $output .= "  referrer: " . referrer() . "\n";
76
  $output .= "  nogrid: " . $nogrid . "\n";
77
  $output .= "  uid: " . $Bc_sql::LOGGEDIN . "\n";
78
  $output .= "  user's selected tid: " . User::get_user_theme() . "\n";
79
  $output .= "  selected theme data";
80
  if ($override_theme ne 0) {
81
    $output .= " (tid provided via URL";
82
    if ($override_theme eq -1) { $output .= ", but it's not valid, falling back to default - guest, or loggedin theme selected"; }
83
    elsif ($override_theme eq -2) { $output .= ", but the DB failed to find data, falling back to default"; }
84
    $output .= ")";
85
  } else {
86
    $output .= " (default theme)";
87
  }
88
  $output .= ":\n";
89
90
  if (ref $THEME_DATA eq "HASH") {
91
  if (keys %$THEME_DATA) {
92
      foreach my $key (sort keys %$THEME_DATA) {
93
        $output .= "    $key = $THEME_DATA->{$key}\n";
94
      }
95
    } else {
96
    $output .= "  no keys in hash of \$THEME_DATA!!\n";
97
    $output .= "  \$THEME_DATA's value: $THEME_DATA\n";
98
  }
99
  } else {
100
    $output .= "  no user theme data!\n";
101
  }
102
  $output .= "*/\n";
103
104
  $output .= "/*\n";
105
  $output .= "/////////////////////////////////////////////////////////////////////\n";
106
  $output .= "                          sassyness\n";
107
  $output .= "/////////////////////////////////////////////////////////////////////\n";
108
  $output .= "*/\n";
109
110
  print pre_html_header({type=>"text/css", skipmaintcheck=>1});
111
  print $output;
112
  exit 1;
113
}
114
115
my $globals = read_text("./css/globals.sass");
116
my $mixins = read_text("./css/mixins.sass");
117
my $common = read_text("./css/common.sass");
118
$common .= read_text("./css/buttons.sass");
119
$common .= read_text("./css/inputs.sass");
120
$common .= read_text("./css/layout.sass");
121
$common .= read_text("./css/html.sass");
122
$common .= read_text("./css/spacers.sass");
123
if (isUserAdmin()) { $common .= read_text("./css/admin.sass"); }
124
125
# filter global vars
126
$globals =~ s/-\[BG_CLR\]-/$THEME_DATA->{bg_clr}/g;
127
$globals =~ s/-\[BG_IMG\]-/'$THEME_DATA->{bg_image}'/g;
128
$globals =~ s/-\[BODY_CLR\]-/$THEME_DATA->{body_clr}/g;
129
$globals =~ s/-\[BODY_CLR_DARK\]-/$THEME_DATA->{body_clr_dark}/g;
130
$globals =~ s/-\[BOLD_CLR\]-/$THEME_DATA->{bold_clr}/g;
131
$globals =~ s/-\[BOLD_SHADOW_CLR\]-/$THEME_DATA->{bold_shadow_clr}/g;
132
$globals =~ s/-\[BORDERS_CLR\]-/$THEME_DATA->{borders_clr}/g;
133
$globals =~ s/-\[BUTTON_BG\]-/$THEME_DATA->{button_bg}/g;
134
$globals =~ s/-\[BUTTON_CLR\]-/$THEME_DATA->{button_clr}/g;
135
$globals =~ s/-\[GRADIENT_DARK\]-/$THEME_DATA->{gradient_dark}/g;
136
$globals =~ s/-\[GRADIENT_LIGHT\]-/$THEME_DATA->{gradient_light}/g;
137
$globals =~ s/-\[INPUT_BG\]-/$THEME_DATA->{input_bg}/g;
138
$globals =~ s/-\[INPUT_BOX_SHADOW_CLR\]-/$THEME_DATA->{input_box_shadow_clr}/g;
139
$globals =~ s/-\[INPUT_TEXT_SHADOW_CLR\]-/$THEME_DATA->{input_text_shadow_clr}/g;
140
$globals =~ s/-\[ITALIC_SHADOW_CLR\]-/$THEME_DATA->{italic_shadow_clr}/g;
141
$globals =~ s/-\[INPUT_CLR\]-/$THEME_DATA->{input_clr}/g;
142
$globals =~ s/-\[INPUT_TEXT_SHADOW_CLR\]-/$THEME_DATA->{input_text_shadow_clr}/g;
143
$globals =~ s/-\[LINK_CLR\]-/$THEME_DATA->{link_clr}/g;
144
$globals =~ s/-\[SELECT_BG\]-/$THEME_DATA->{select_bg}/g;
145
$globals =~ s/-\[SELECT_CLR\]-/$THEME_DATA->{select_clr}/g;
146
$globals =~ s/-\[SUBTITLE_CLR\]-/$THEME_DATA->{subtitle_clr}/g;
147
$globals =~ s/-\[SUBTITLE_SHADOW_CLR\]-/$THEME_DATA->{subtitle_shadow_clr}/g;
148
$globals =~ s/-\[TITLE_CLR\]-/$THEME_DATA->{title_clr}/g;
149
$globals =~ s/-\[TITLE_SHADOW_CLR\]-/$THEME_DATA->{title_shadow_clr}/g;
150
151
# fonts
152
$globals =~ s/-\[NORMAL_FONT\]-/Times New Roman/g;
153
$globals =~ s/-\[WELCOME_FONT\]-/Trebuchet MS/g;
154
$globals =~ s/-\[TITLE_FONT\]-/Book Antiqua/g;
155
$globals =~ s/-\[LINK_FONT\]-/Book Antiqua/g;
156
$globals =~ s/-\[FUNNY_FONT\]-/Alegreya SC/g;
157
158
# font sizes
159
$globals =~ s/-\[GIANT_FONT_SIZE\]-/24pt/g;
160
$globals =~ s/-\[LARGE_FONT_SIZE\]-/16pt/g;
161
$globals =~ s/-\[MEDIUM_FONT_SIZE\]-/14pt/g;
162
$globals =~ s/-\[NORMAL_FONT_SIZE\]-/12pt/g;
163
$globals =~ s/-\[NEARSMALL_FONT_SIZE\]-/11pt/g;
164
$globals =~ s/-\[SMALL_FONT_SIZE\]-/10pt/g;
165
$globals =~ s/-\[NEARTINY_FONT_SIZE\]-/9pt/g;
166
$globals =~ s/-\[TINY_FONT_SIZE\]-/8pt/g;
167
168
# filter common sass
169
if ($common =~ /\-\[BODY\-BG\-IMAGE\]\-/) {
170
  if (not $nobg) {
171
    if ($THEME_DATA->{bg_image}) {
172
      my $css = "  background-attachment: fixed;\n";
173
      $css .= "  background-image: url('/img.pl?s=f&i=$THEME_DATA->{bg_image}');\n";
174
      if ($THEME_DATA->{bg_image} =~ /wallpaper/) {
175
        $css .= "  background-repeat: no-repeat;\n";
176
        $css .= "  background-size: 100% 100%;\n";
177
      } else {
178
        $css = "  background-image: none;\n";
179
      }
180
181
      $common =~ s/\-\[BODY\-BG\-IMAGE\]\-/$css/g;
182
    }
183
  } else {
184
    $common =~ s/\-\[BODY\-BG\-IMAGE\]\-//g;
185
  }
186
}
187
188
$output .= $globals . "\n\n";
189
$output .= $mixins . "\n\n";
190
191
#
192
# initially, i was writing for desktop only.
193
# i've had to "fit" responsiveness into this mess!
194
#
195
# with that said, desktop layout is as follows (each list item represents a grid row):
196
#   when loggedin:
197
#     - header: a left aligned DIV for logo, a centered DIV for msgs, and a right aligned DIV for logout
198
#     - navbar: a left aligned DIV for menu and right aligned 'gridded' DIV for 'searchbar'
199
#     - contents-container: a DIV for main content area (which in of itself is a grid!)
200
#     - footer: a 'gridded' DIV for footer
201
#   when NOT loggedin:
202
#     - header: a left aligned DIV for logo, a centered DIV for msgs, and a right aligned DIV for logout
203
#     - contents-container: a DIV for main content area (i don't think it's 'gridded')
204
#     - footer: a 'gridded' DIV for footer
205
#
206
# when client is a mobile device:
207
#   when loggedin:
208
#     - header: a left aligned DIV for logo and a right aligned DIV for logout
209
#     - msgs: a DIV for msgs
210
#     - navbar: a left aligned DIV for menu and a right aligned 'gridded' DIV for searchbar
211
#     - contents-container, a 'gridded' DIV for main-content-area
212
#     - footer: a 'gridded' DIV for footer
213
#   when NOT loggedin:
214
#     - header: a left aligned DIV for logo and a right aligned DIV for logout
215
#     - msgs: a DIV for msgs
216
#     - contents-container: a DIV for main content area (which in of itself is a grid!)
217
#     - footer: a 'gridded' DIV for footer
218
#
219
220
my $body_rows = "min-content 1fr min-content";
221
my $body_rows_mobile = "min-content 1fr min-content";
222
my $content_cols = "1fr";
223
my $foot_cols = "1fr";
224
my $foot_cols_mobile = "min-content";
225
my $foot_rows_mobile = "min-content min-content";
226
227
if ($LOGGEDIN) {
228
  $body_rows = "min-content min-content 1fr min-content";
229
  $body_rows_mobile = "min-content min-content 1fr min-content";
230
  $content_cols = "minmax(min-content, 200px) 1fr auto";
231
  $foot_cols = "1fr 1fr";
232
}
233
234
$common =~ s/\-\[BODY_ROWS\]\-/$body_rows/g;
235
$common =~ s/\-\[BRM\]\-/$body_rows_mobile/g;
236
$common =~ s/\-\[CONTENT_COLS\]\-/$content_cols/g;
237
$common =~ s/\-\[FOOT_COLS\]\-/$foot_cols/g;
238
$common =~ s/\-\[FCM\]\-/$foot_cols_mobile/g;
239
$common =~ s/\-\[FRM\]\-/$foot_rows_mobile/g;
240
241
my @c = split(/\n/, $common);
242
243
if ($nogrid) {
244
  my $start = 0;
245
  foreach my $line (@c) {
246
    if (not $start) {
247
      if ($line =~ /\[GRID\]/) {
248
        $start = 1;
249
      }
250
    }
251
252
    if ($start) {
253
      if ($line =~ /\[\/GRID\]/) { $start = 0; }
254
      $line = "";
255
    }
256
  }
257
} else {
258
  foreach my $line (@c) {
259
    $line =~ s/\[GRID\]//g;
260
    $line =~ s/\[\/GRID\]//g;
261
  }
262
}
263
264
if ($LOGGEDIN) {
265
  my $start = 0;
266
  my $finish = 0;
267
  foreach my $line (@c) {
268
    if (not $start) {
269
      if ($line =~ /\[NOTLOGGEDIN\]/) {
270
        $start = 1;
271
      }
272
    }
273
274
    if ($start) {
275
      if ($line =~ /\[\/NOTLOGGEDIN\]/) { $start = 0; }
276
      $line = "";
277
    }
278
  }
279
280
} elsif (not $LOGGEDIN) {
281
  my $start = 0;
282
  my $finish = 0;
283
  foreach my $line (@c) {
284
    if (not $start) {
285
      if ($line =~ /\[LOGGEDIN\]/) {
286
        $start = 1;
287
      }
288
    }
289
290
    if ($start) {
291
      if ($line =~ /\[\/LOGGEDIN\]/) { $start = 0; }
292
      $line = "";
293
    }
294
  }
295
}
296
297
my @newc = ();
298
foreach my $line (@c) {
299
  if ($line) {
300
    if (length $line) { push @newc, $line; }
301
  }
302
}
303
304
$common = join("\n", @newc);
305
306
####################
307
308
@c = split(/\n/, $common);
309
if (isUserBeta()) {
310
  my $start = 0;
311
  my $finish = 0;
312
  foreach my $line (@c) {
313
    if (not $start) {
314
      if ($line =~ /\[NOTBETA\]/) {
315
        $start = 1;
316
      }
317
    }
318
319
    if ($start) {
320
      if ($line =~ /\[\/NOTBETA\]/) { $start = 0; }
321
      $line = "";
322
    }
323
  }
324
325
} else {
326
  my $start = 0;
327
  my $finish = 0;
328
  foreach my $line (@c) {
329
    if (not $start) {
330
      if ($line =~ /\[BETA\]/) {
331
        $start = 1;
332
      }
333
    }
334
335
    if ($start) {
336
      if ($line =~ /\[\/BETA\]/) { $start = 0; }
337
      $line = "";
338
    }
339
  }
340
}
341
342
@newc = ();
343
foreach my $line (@c) {
344
  if ($line) {
345
    if (length $line) {
346
      push @newc, $line;
347
    }
348
  }
349
}
350
351
$common = join("\n", @newc);
352
353
$common =~ s/\[LOGGEDIN\]//g;
354
$common =~ s/\[\/LOGGEDIN\]//g;
355
$common =~ s/\[NOTLOGGEDIN\]//g;
356
$common =~ s/\[\/NOTLOGGEDIN\]//g;
357
$common =~ s/\[BETA\]//g;
358
$common =~ s/\[\/BETA\]//g;
359
$common =~ s/\[NOTBETA\]//g;
360
$common =~ s/\[\/NOTBETA\]//g;
361
362
$output .= $common;
363
364
my $sass = CSS::Sass->new;
365
$output = $sass->compile($output);
366
367
print pre_html_header({type=>"text/css", skipmaintcheck=>1});
368
print $output;
369
370
exit 1;