blob: d5d6ed1b1d7cb90eccebc18aac19f70b83c9721a [file] [log] [blame] [edit]
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_binary", "closure_js_library")
def _internal_closure_fragment_export_impl(ctx):
ctx.actions.write(
output = ctx.outputs.out,
content = """
goog.require('%s');
goog.exportSymbol('_', %s);
""" % (ctx.attr.module, ctx.attr.function),
)
_internal_closure_fragment_export = rule(
implementation = _internal_closure_fragment_export_impl,
attrs = {
"function": attr.string(mandatory = True),
"module": attr.string(mandatory = True),
},
outputs = {"out": "%{name}.js"},
)
def _closure_fragment_impl(ctx):
defs = ctx.attr.defines + [
"goog.userAgent.ASSUME_MOBILE_WEBKIT=true",
"goog.userAgent.product.ASSUME_ANDROID=true",
]
def closure_fragment(
name,
module,
function,
browsers = None,
**kwargs):
if browsers == None:
browsers = []
if type(browsers) != "list":
fail("browsers must be None or a list of strings")
exports_file_name = "_%s_exports" % name
_internal_closure_fragment_export(
name = exports_file_name,
module = module,
function = function,
)
exports_lib_name = "%s_lib" % exports_file_name
closure_js_library(
name = exports_lib_name,
srcs = [exports_file_name],
deps = kwargs.get("deps", []),
)
# Wrap the output in two functions. The outer function ensures the
# compiled fragment never pollutes the global scope by using its
# own scope on each invocation. We must import window.navigator into
# this unique scope since Closure's goog.userAgent package assumes
# navigator and document are defined on goog.global. Normally, this
# would be window, but we are explicitly defining the fragment so that
# goog.global is _not_ window.
# See http://code.google.com/p/selenium/issues/detail?id=1333
wrapper = (
"function(){" +
"return (function(){%output%; return this._.apply(null,arguments);}).apply({" +
"navigator:typeof window!='undefined'?window.navigator:null," +
"document:typeof window!='undefined'?window.document:null" +
"}, arguments);}"
)
browser_defs = {
"*": [],
"android": [
"--define=goog.userAgent.ASSUME_MOBILE_WEBKIT=true",
"--define=goog.userAgent.product.ASSUME_ANDROID=true",
],
"chrome": [
"--define=goog.userAgent.ASSUME_WEBKIT=true",
"--define=goog.userAgent.product.ASSUME_CHROME=true",
"--define=goog.NATIVE_ARRAY_PROTOTYPES=false",
"--use_types_for_optimization=false",
],
"ie": [
"--define=goog.userAgent.ASSUME_IE=true",
],
"ios": [
"--define=goog.userAgent.ASSUME_MOBILE_WEBKIT=true",
],
"firefox": [
"--define=goog.userAgent.ASSUME_GECKO=true",
"--define=goog.userAgent.product.ASSUME_FIREFOX=true",
],
}
for browser, defs in browser_defs.items():
if len(browsers) > 0 and (browser == "*" or browser not in browsers):
continue
bin_name = name
if browser != "*":
bin_name = bin_name + "-" + browser
closure_js_binary(
name = bin_name,
deps = [":" + exports_lib_name],
defs = kwargs.get("defs", []) + defs,
output_wrapper = wrapper,
visibility = kwargs.get("visibility"),
)