load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_binary", "closure_js_library") EXPORT_FUNCTION_NAME = "se_exportedFunctionSymbol" def _internal_closure_fragment_export_impl(ctx): ctx.actions.write( output = ctx.outputs.out, content = """ goog.require('%s'); goog.exportSymbol('%s', %s); """ % (ctx.attr.module, EXPORT_FUNCTION_NAME, 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." + EXPORT_FUNCTION_NAME + ".apply(null,arguments);}).apply(window, 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"), )