#
# Google Ads inserts the following three lines of code into the HTML to display
# a banner.
#
#
#
#
#
# Altruistically by removing them in the development environment we protect
# against click fraud, but the reality is that they are simply annoying and
# unecessary.
#
# But we need something to indicate their presence, location, size, and
# accuracy on the page. This middleware accomplishes that for us by removing
# the the two 'script' lines and replacing the 'ins' with a div of the same
# size, moving the 'data-???' attributes into the content so that the ads can
# be validated by inspection.
#
# This middleware is invoked by adding the following to
# config/environments/deploy.rb:
#
# config.middleware.use 'GoogleAdMunger'
#
class GoogleAdMunger
def initialize(app)
@app = app
# Define the regexp for the items we wich to remove. Note the last one
# contains matches. This regexp isn't very robust, but we control the HTML
# so don't have to worry about multiple line issues and spacing.
@regexp = Regexp.new(
Regexp.escape(%q!!) +
'|' +
Regexp.escape(%q!!) +
'|' +
%q!!
)
# Define what we want to happen to the matched lines. If it's the `ins`
# tag replace it with our custom div. Otherwise replace it with an empty
# string.
@regexp_block = ->(m, style, data) do
m =~ /Google Ad: #{data}! : ''
end
end
def call(env)
status, headers, response = @app.call(env)
# Technically the development check is redundant, but someone may try to
# include the middleware elsewhere. Also, only do it for html requests.
if Rails.env.development? && headers['Content-Type'] =~ %r!text/html!
# Get the current body. Rack is a little weird, hence the .each block.
body = ''
response.each {|e| body << e}
# Run our replacements. If the grouped matches change above
# change them here as well. Not ideal, but it works.
body.gsub!(@regexp) {|m| @regexp_block.call(m, $1, $2) }
# Return the response satisfying Rack's need for .each.
response = [body]
end
[status, headers, response]
end
end