Skip to content

Instantly share code, notes, and snippets.

View searls's full-sized avatar
💚

Justin Searls searls

💚
View GitHub Profile
@searls
searls / extension_murderer_controller.js
Last active August 16, 2024 12:23
There's no way for web developers to prevent 1Password from thinking it can fill one-time-passwords (OTP) if they have autocomplete=one-time-code. This is madness, because 80% of these are SMS/email, and 1Password offers no way to fill these.
import { Controller } from '@hotwired/stimulus'
const BANNED_NODES = ['com-1password-button', 'com-1password-menu']
export default class extends Controller {
connect () {
this.observer = new window.MutationObserver(mutations => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (BANNED_NODES.includes(node.nodeName.toLowerCase())) {
node.remove()
@searls
searls / resets_session_but_its_still_thursday_i_need_these.rb
Created August 15, 2024 12:28
Was genuinely surprised Rails `reset_session` doesn't accept a list of exceptions
# If you have any session variables that should survive a logout, add them to
# the except_for array. Usage from a controller:
#
# ResetsSessionButItsStillThursdayINeedThese.new.reset(self,
# except_for: [:has_logged_in_before])
class ResetsSessionButItsStillThursdayINeedThese
def reset(receiver, except_for: [])
backup = except_for.map { |key| [key, receiver.session[key]] }
receiver.reset_session
@searls
searls / fake_markdown.rb
Created July 16, 2024 14:52
I was disappointed with the faker gem's Markdown and Lorem modules, so I wrote a custom thing that produced realistic-length paragraphs with just enough markdown junk sprinkled in to know that it's rendering correctly in my app
require "faker"
def lorem_paragraphs
rand(2..4).times.map {
rand(4..6).times.map {
Faker::Lorem.sentence(word_count: rand(10..40))
}.join(" ")
}.join("\n\n")
end
@searls
searls / tailwind_class_builder.rb
Created July 3, 2024 17:19
Here's a custom Tailwind FormBuilder for Rails. To set this up, just set ` ActionView::Base.default_form_builder = FormBuilders::TailwindFormBuilder` somewhere (and customize all the CSS classes)
class TailwindClassBuilder
include ActionView::Helpers::TagHelper
def button_classes(options)
button_type = options.delete(:button_type) { :button }
class_names(
# general classes
"mt-4 px-1 sm:px-3 py-sm sm:py-1 font-semibold bg-transparent border rounded",
case button_type
# This is a stupid utility to squelch stdout output via puts (could do the same
# for warn; could also override stdout entirely)
#
# Usage in a test, after requiring and including it:
#
# setup do
# suppress_puts([
# /Execution context was destroyed, most likely because of a navigation/
# ])
# end
@searls
searls / validates_deeply.rb
Last active April 23, 2024 16:07
Is this overkill? Is there some other nice way to do this?
class ValidatesDeeply
Failure = Struct.new(:model, :message)
Result = Struct.new(:valid?, :failures)
def validate(model, visited = Set.new)
return Result.new(true) if visited.include?(model)
visited.add(model)
combine_results(Result.new(model.valid?, extract_failures(model)), *validate_associations(model, visited))
end
:root,
.light {
--accent: 183 64 233;
--accent-bright: 183 64 233;
--accent-light: 217 155 244;
--bg-primary: 249 249 249;
--bg-secondary: 230 230 230;
--border-primary: 17 24 39;
const css4ColorsToLegacyRgbaPlugin = {
postcssPlugin: 'these-colors-dont-run',
Once (root) {
root.walkDecls((decl) => {
const rgbRegex = /rgb\((\d{1,3})\s+(\d{1,3})\s+(\d{1,3})\s*(?:\/\s*(\d+\.?\d*))?\)/g
decl.value = decl.value.replace(rgbRegex, (match, r, g, b, a) => {
if (!a || a === '1' || a === '1.0') {
return `rgb(${r}, ${g}, ${b})`
} else {
return `rgba(${r}, ${g}, ${b}, ${a})`
@searls
searls / ensures_logger_broadcasts_to_stdout.rb
Last active March 4, 2024 19:18
This logger wrapper I wrote.
# Leverages the BroadcastLogger introduced in Rails 7.1 to wrap the current
# logger in a new logger that broadcasts to both the current logger and $stdout
#
# (Announcement: https://rubyonrails.org/2023/9/29/this-week-in-rails)
#
# If the current logger already broadcasts to $stdout, it will not be wrapped,
# making it safe to call this method multiple times without knowing the current
# logging "sitch".
#
# Usage probably looks something like this:

Running with patch

$ QUEUE_ADAPTER=async ./fix-preview-image-race-condition.rb 

Yields

Creating a post and uploading a video