Created
March 11, 2012 18:21
-
-
Save johnthethird/2017532 to your computer and use it in GitHub Desktop.
Batman binding for executing script blocks in views
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Execscripts.coffee | |
| # John Lynch / Rigel Group, LLC | |
| # Open source under the MIT License. | |
| # | |
| # Create a new binding that marks a specific node as having children scripts blocks, and then executes those script | |
| # blocks as soon as the node has been added to the DOM by Batman. (This is necessary as many jQuery-type plugins | |
| # wont work if run on an isolated node before it has been added to the DOM.) | |
| # | |
| # (Thanks to SO for some of this code. http://stackoverflow.com/questions/220188/how-can-i-determine-if-a-dynamically-created-dom-element-has-been-added-to-the-d) | |
| # | |
| # <div data-execscripts="true"> | |
| # <h1>Title</h1> | |
| # <script type="text/javascript"> | |
| # alert("Hi Mom!"); | |
| # </script | |
| # </div> | |
| # | |
| # | |
| Batman.DOM.readers.execscripts = (node, key, context, renderer) -> | |
| new Batman.DOM.ExecscriptBinding(node, key, context, renderer) | |
| true | |
| class Batman.DOM.ExecscriptBinding extends Batman.DOM.AbstractBinding | |
| bindImmediately: false | |
| constructor: -> | |
| super | |
| # Only run the script blocks once this node has been added to the DOM by Batman | |
| @_executeOnLoad(@node, @_exec_body_scripts) if @value | |
| _exec_body_scripts: (elem) => | |
| scripts = [] | |
| for child in elem.childNodes | |
| scripts.push(child) if @_isScriptNode(child) | |
| for script in scripts | |
| script.parentNode?.removeChild(script) | |
| @_evalScript(script) | |
| _isScriptNode: (elem) => | |
| elem.nodeName && elem.nodeName.toLowerCase() == "script" && (!elem.type || elem.type.toLowerCase() == "text/javascript") | |
| _evalScript: (elem) => | |
| data = (elem.text || elem.textContent || elem.innerHTML || "" ) | |
| head = document.getElementsByTagName("head")[0] || document.documentElement | |
| script = document.createElement("script") | |
| script.type = "text/javascript" | |
| try | |
| script.appendChild(document.createTextNode(data)) | |
| catch e | |
| script.text = data | |
| head.insertBefore(script, head.firstChild) | |
| head.removeChild(script) | |
| _isInDOMTree: (node) => | |
| !! @_findUltimateAncestor(node).body | |
| _findUltimateAncestor: (node) => | |
| ancestor = node | |
| (ancestor = ancestor.parentNode) while ancestor.parentNode | |
| ancestor | |
| _executeOnLoad: (node, func) => | |
| if @_isInDOMTree(node) then func(node) else setTimeout( (() => @_executeOnLoad(node, func)), 100) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment