<commit_before>= Dependencies
<NAME>
2016-07-29
:type: reference
:toc: macro
:icons: font

ifdef::env-github,env-browser[:outfilesuffix: .adoc]

toc::[]

Every non-trivial ClojureScript application will eventually need to
consume code created by others. ClojureScript developers can of course
take advantage of code authored using ClojureScript. However,
ClojureScript developers can also consume arbitrary JavaScript code,
whether or not it was written with ClojureScript in mind.

This guide assumes you've worked through the <<xref/../../../guides/quick-start#,Quick Start>>
guide, and are equipped with the dependencies introduced there.

[[consuming-javascript-code]]
== Consuming JavaScript Code

While you can consume any JavaScript code, the optimal mechanism for
including that code is not always the same. The following sections
explore the various options for utilizing third party JavaScript code.

[[closure-library]]
=== Closure Library

The easiest JavaScript code to consume is that of Google's
https://github.com/google/closure-library[Closure Library] (GCL), which
is automatically bundled with ClojureScript. GCL is a massive collection
of JavaScript code organized into namespaces much like ClojureScript
code itself. Thus, you can require a namespace from GCL in the same
fashion as a ClojureScript namespace. The following example demonstrates
basic usage:

[source,clojure]
----
(ns hello-world.core
  (:require [goog.dom :as dom]
            [goog.dom.classes :as classes]
            [goog.events :as events])
  (:import [goog Timer]))
    
(let [element (dom/createDom "div" "some-class" "Hello, World!")]
  (classes/enable element "another-class" true)
  (-> (dom/getDocument)
    .-body
    (dom/appendChild element))
  (doto (Timer. 1000)
    (events/listen "tick" #(.warn js/console "still here!"))
    (.start)))
----

See
http://clojurescriptmadeeasy.com/blog/when-do-i-use-require-vs-import.html[this
blog post] on the difference between `:import` and `:require` for
closure libs.

The gist of it is: use `:import` for Closure classes and enums, and use
`:require` for everything else.

[[external-javascript-libraries]]
=== External JavaScript Libraries

In cases where GCL doesn't contain the functionality you want, or you'd
otherwise like to take advantage of a third party JavaScript library,
you can use the code directly.

Let's consider the case where we want to use a fancy JavaScript library
called yayQuery. To utilize a JavaScript library, simply reference the
JavaScript as normal. Whether the file is loaded externally or inline
makes no difference, both will be applied in the same fashion at
runtime. To make things simple, we'll define this library inline:

....
<script type="text/javascript">
    yayQuery = function() {
        var yay = {};
        yay.sayHello = function(message) {
            console.log(message);
        }
        yay.getMessage = function() {
            return 'Hello, world!';
        }
       return yay;
    };
</script>
....

To use this library from ClojureScript, we can simply refer to the
symbols directly. If you build the following code using
`{:optimizations :none}`, everything will work fine and you will see a
message in your JavaScript console.

[source,clojure]
----
(ns hello-world.core)
  
(let [yay (js/yayQuery)]
  (.sayHello yay (.getMessage yay)))
----

While this works fine with unoptimized code, it will fail when we use
advanced optimizations. Try compiling the same code with
`{:optimizations :advanced}` and reload your browser. You will receive
an error message similar to the following (it may not be exactly as
below):

[source]
----
Uncaught TypeError: sa.B is not a function
----

Why did this happen? When using advanced optimizations, the Google
Closure Compiler will rename symbols. In most cases, this is not a
problem, as all instances of the same symbol will be renamed
consistently. However, in this case the external symbol (the name in the
JavaScript code) is _separate_ from our compilation unit, so the names
no longer match. Fortunately, we have options for resolving this issue
without losing all of the benefits of advanced compilation.
<commit_msg>Fix bug onMouseOver event in source-highlight box<commit_after>= Dependencies
<NAME>
2016-07-29
:type: reference
:toc: macro
:icons: font

ifdef::env-github,env-browser[:outfilesuffix: .adoc]

toc::[]

Every non-trivial ClojureScript application will eventually need to
consume code created by others. ClojureScript developers can of course
take advantage of code authored using ClojureScript. However,
ClojureScript developers can also consume arbitrary JavaScript code,
whether or not it was written with ClojureScript in mind.

This guide assumes you've worked through the <<xref/../../../guides/quick-start#,Quick Start>>
guide, and are equipped with the dependencies introduced there.

[[consuming-javascript-code]]
== Consuming JavaScript Code

While you can consume any JavaScript code, the optimal mechanism for
including that code is not always the same. The following sections
explore the various options for utilizing third party JavaScript code.

[[closure-library]]
=== Closure Library

The easiest JavaScript code to consume is that of Google's
https://github.com/google/closure-library[Closure Library] (GCL), which
is automatically bundled with ClojureScript. GCL is a massive collection
of JavaScript code organized into namespaces much like ClojureScript
code itself. Thus, you can require a namespace from GCL in the same
fashion as a ClojureScript namespace. The following example demonstrates
basic usage:

[source,clojure]
----
(ns hello-world.core
  (:require [goog.dom :as dom]
            [goog.dom.classes :as classes]
            [goog.events :as events])
  (:import [goog Timer]))
    
(let [element (dom/createDom "div" "some-class" "Hello, World!")]
  (classes/enable element "another-class" true)
  (-> (dom/getDocument)
    .-body
    (dom/appendChild element))
  (doto (Timer. 1000)
    (events/listen "tick" #(.warn js/console "still here!"))
    (.start)))
----

See
http://clojurescriptmadeeasy.com/blog/when-do-i-use-require-vs-import.html[this
blog post] on the difference between `:import` and `:require` for
closure libs.

The gist of it is: use `:import` for Closure classes and enums, and use
`:require` for everything else.

[[external-javascript-libraries]]
=== External JavaScript Libraries

In cases where GCL doesn't contain the functionality you want, or you'd
otherwise like to take advantage of a third party JavaScript library,
you can use the code directly.

Let's consider the case where we want to use a fancy JavaScript library
called yayQuery. To utilize a JavaScript library, simply reference the
JavaScript as normal. Whether the file is loaded externally or inline
makes no difference, both will be applied in the same fashion at
runtime. To make things simple, we'll define this library inline:

....
<script type="text/javascript">
    yayQuery = function() {
        var yay = {};
        yay.sayHello = function(message) {
            console.log(message);
        }
        yay.getMessage = function() {
            return 'Hello, world!';
        }
       return yay;
    };
</script>
....

To use this library from ClojureScript, we can simply refer to the
symbols directly. If you build the following code using
`{:optimizations :none}`, everything will work fine and you will see a
message in your JavaScript console.

[source,clojure]
----
(ns hello-world.core)
  
(let [yay (js/yayQuery)]
  (.sayHello yay (.getMessage yay)))
----

While this works fine with unoptimized code, it will fail when we use
advanced optimizations. Try compiling the same code with
`{:optimizations :advanced}` and reload your browser. You will receive
an error message similar to the following (it may not be exactly as
below):

[source,javascript]
----
Uncaught TypeError: sa.B is not a function
----

Why did this happen? When using advanced optimizations, the Google
Closure Compiler will rename symbols. In most cases, this is not a
problem, as all instances of the same symbol will be renamed
consistently. However, in this case the external symbol (the name in the
JavaScript code) is _separate_ from our compilation unit, so the names
no longer match. Fortunately, we have options for resolving this issue
without losing all of the benefits of advanced compilation.

{'fraction_non_alphanumeric': 0.08624181060154854, 'fraction_numerical': 0.0028588445503275758, 'mean_word_length': 4.009546539379475, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7372796', 'n_tokens_mistral': 2362, 'n_tokens_neox': 2218, 'n_words': 1056}