{"id":996,"date":"2013-01-25T00:38:54","date_gmt":"2013-01-25T00:38:54","guid":{"rendered":"http:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/?p=996"},"modified":"2013-01-24T19:38:55","modified_gmt":"2013-01-25T00:38:55","slug":"opening-links-in-flash","status":"publish","type":"post","link":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2013\/01\/opening-links-in-flash\/","title":{"rendered":"Opening Links in Flash"},"content":{"rendered":"<p>Opening links to web pages from AS3 is pretty well covered in various online documentation. \u00a0It&#8217;s similarly straightforward in Haxe. \u00a0Recently, however, I came to realize that it wasn&#8217;t normal Flash behavior that Haxe programs would only open links in the browser or standalone player if served from a server, \u00a0even localhost, and not from a local &#8216;file:&#8217; URL.<\/p>\n<p>It turned out this was because Haxe by default compiles to a different, more restricted network security model than that to which the Adobe tools compile. \u00a0Even if opened from a <code>MouseEvent<\/code>, the navigation calls are blocked, as is all network access from a local SWF. \u00a0To enable this network access and allow links to be opened, you have to compile with the <code>network-sandbox<\/code> compiler flag (<code>-Dnetwork-sandbox<\/code>). \u00a0The documentation for it is a little non-intuitively ambiguous, but that actually enables more access than the default. \u00a0Links should now all work, from a hosted or local SWF.<\/p>\n<p>As a sidenote, the code to open a link in Haxe looks like this:<\/p>\n<pre>\r\nimport flash.Lib;\r\nimport flash.text.TextField;\r\nimport flash.display.Sprite;\r\nimport flash.net.URLRequest;\r\nimport flash.events.MouseEvent;\r\nimport flash.events.Event;\r\n\r\nclass Sample extends Sprite\r\n{\r\n   public function new()\r\n   {\r\n      super();\r\n\r\n      Lib.current.stage.addChild(this);\r\n\r\n      var label:TextField=new TextField();\r\n      label.width=800;\r\n      label.text=\"Click to open google!\";\r\n      addChild(label);\r\n      Lib.current.stage.addEventListener(MouseEvent.CLICK,onClick);\r\n   }\r\n\r\n   public function onClick(inEvent:MouseEvent)\r\n   {\r\n     Lib.getURL(new URLRequest(\"http:\/\/www.google.com\"));\r\n   }\r\n\r\n   public static function main()\r\n   {\r\n     new Sample();\r\n   }\r\n}\r\n<\/pre>\n<p>Its equivalent in AS3 looks like the following:<\/p>\n<pre>\r\npackage {\r\n\r\n  import flash.display.Sprite;\r\n  import flash.text.TextField;\r\n  import flash.net.URLRequest;\r\n  import flash.events.MouseEvent;\r\n  import flash.events.Event;\r\n\r\n  import flash.net.navigateToURL;\r\n  import flash.net.URLRequest;\r\n\r\n public class LinkTest extends Sprite {\r\n    public function LinkTest() {\r\n      var label:TextField = new TextField();\r\n      label.width = 200;\r\n      label.text = \"Click here\";\r\n      addChild(label);\r\n\r\n\r\n      label.addEventListener(MouseEvent.CLICK, onClick);\r\n    }\r\n\r\n\r\n    public function onClick(e:MouseEvent) {\r\n      navigateToURL(new URLRequest(\"http:\/\/google.com\"));\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>Internally Haxe&#8217;s <code>flash.Lib<\/code> is actually literally just calling <code>navigateToURL<\/code> via a pretty wild looking cast on the global symbol table entry, since Haxe has no concept of package level functions like AS3 does.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Opening links to web pages from AS3 is pretty well covered in various online documentation. \u00a0It&#8217;s similarly straightforward in Haxe. \u00a0Recently, however, I came to realize that it wasn&#8217;t normal Flash behavior that Haxe programs would only open links in the browser or standalone player if served from a server, \u00a0even localhost, and not from &hellip; <a href=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2013\/01\/opening-links-in-flash\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[58],"tags":[69,82],"class_list":["post-996","post","type-post","status-publish","format-standard","hentry","category-code","tag-flash","tag-haxe"],"_links":{"self":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/996","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/comments?post=996"}],"version-history":[{"count":3,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/996\/revisions"}],"predecessor-version":[{"id":1002,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/996\/revisions\/1002"}],"wp:attachment":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/media?parent=996"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/categories?post=996"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/tags?post=996"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}