AtlasCamp 2013: Modernizing your Plugin UI

628 views

Published on

Published in: Technology, Design
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
628
On SlideShare
0
From Embeds
0
Number of Embeds
96
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

AtlasCamp 2013: Modernizing your Plugin UI

  1. 1. @atlassian #atlascamp
  2. 2. Modernizing Your Plugin UI Jonathon Creenaune, Front End Architect, Atlassian
  3. 3. Build more features
  4. 4. Build more features Make features better
  5. 5. Make features better
  6. 6. Beauty
  7. 7. Beauty Interactivity
  8. 8. Beauty
  9. 9. AUI <header class="aui-page-header">   <div class="aui-page-header-inner">     my header text   </div> </header>
  10. 10. Side-by-side <header class="aui-page-header">   <div class="aui-page-header-inner">     my header text   </div> </header>
  11. 11. Side-by-side <header class="aui-page-header"> {call aui.page.pageHeader}   <div class="aui-page-header-inner">   {param content}     my header text     my header text   </div>   {/param} </header> {/call}
  12. 12. AUI 5.0 is in JIRA 6.0 Confluence 5.0 Bamboo 4.3 Stash 2.0 FE/CRU 3.0
  13. 13. Targeting non-soy platforms
  14. 14. “ not just a side-effect of the technology you used to create a page ” URLs should be designed for the user,
  15. 15. /secure/MemeAction.jspa /plugins/servlet/memes
  16. 16. /memes /secure/MemeAction.jspa /memes/{x} /secure/MemeAction.jspa?key={x} /memes/create/ => /secure/MemeAction.jspa?upload= /memes/create/{x} /secure/MemeAction.jspa?createBaseImageKey={x} /memes/create /secure/MemeAction.jspa?create=
  17. 17. Pretty URLs <routing key="meme-pretty-urls" path="/memes"> <get from="" to="/secure/MemeAction.jspa"/> <get from="/create/" to="/secure/MemeAction.jspa?upload="/> <get from="/create/{key}" to="/secure/MemeAction.jspa? createBaseImageKey={key}"/> <get from="/create" to="/secure/MemeAction.jspa?create="/> <get from="/{key}" to="/secure/MemeAction.jspa?key={key}"/> </routing>
  18. 18. Pretty URLs P2: Yes Old products: Yes Connect: Yes
  19. 19. Interactivity
  20. 20. Getting code closer to the user
  21. 21. Pushstate history.pushState(stateObject, title, url); // Using history.js History.pushState(null, null, url);
  22. 22. Pushstate gallery.onSelectImage(function(key) { // Add it to the URL History.pushState(null, null, AJS.contextPath() + “/memes” + key); // Load the hero image hero.load($container, key); });
  23. 23. Pushstate - back / forward History.Adapter.bind(window, 'statechange', function() { var match; if (match = getUrl().match(/^$/)) { // gallery gallery.load($container); } else if (match = getUrl().match(/^/(.*)$/)) { // hero hero.load($container, match[1]); } });
  24. 24. Pushstate P2: Yes Old products: Yes Connect: Yes
  25. 25. Soy renders on server and on client
  26. 26. Render on server <webwork1 key="meme-webwork" class="java.lang.Object"> <actions> <action name="com.atlassian.meme.action.MemeAction" ...> <view name="hero" type="soy"> :server-templates/meme.page.hero </view> <view name="gallery" type="soy"> :server-templates/meme.page.gallery </view> ...
  27. 27. Render on server $(function() { var $container = getContainer(); hero.initEvents($container); });
  28. 28. Render on client <web-resource key="hero"> <transformation extension="soy"> <transformer key="soyTransformer" /> </transformation> <resource type="download" name="hero.js" location="hero.soy"/> ...
  29. 29. Render on client function render($container, key) { $.get(getMemeUrl(key)).done(function(memeData) { $container.html(meme.hero.main({ meme: memeData })); initEvents($container); ...
  30. 30. Render on client + server P2: Yes Old products: If soy available Connect: JVM server
  31. 31. Injecting Page Data // Bad <script> var myData = “${getMyData}”; </script> // Why? Because it’s an XSS hole <script> var myData = “</script><script>alert(‘naughty’);””; </script>
  32. 32. Injecting Page Data // In action public String getSelectData() { return ImmutableMap.of( “baseImages”, getAllBaseImages(), “baseImagesJson”, marshalAsJson(getAllBaseImages()) ); }
  33. 33. Injecting Page Data // In template <div class="base-images-json" data-base-images-json="{$baseImagesJson}"> </div>
  34. 34. Accessing Page Data // From javascript var myData = AJS.$(".base-images-json"). data("base-images-json");
  35. 35. Page Data P2: Yes Old products: Yes Connect: Yes
  36. 36. Future ...
  37. 37. Injecting Page Data <web-resource key="blah">   <data name="my-data" provider="com.acme.MyDataProvider" />   <resource type="download" name="my-code.js" /> </web-resource>
  38. 38. Injecting Page Data // pageBuilderService is injectable pageBuilderService.getData().set("my-data-key", myJsonable);
  39. 39. Accessing Page Data var data = AJS.data.get("my-plugin:blah:my-data");
  40. 40. Gallery Hero Main Select Create Read files Form Utils Render Meme
  41. 41. Defining Modules define(“create/canvasDrawer”, function() { ... return { drawImage: function() {}, drawText: function() {}, getAsBase64: function() {} } });
  42. 42. Requiring Modules define(“create/main”, [“./formView”, “./canvasDrawer”], function(formView, canvasDrawer) { formView.onSubmit(function() { canvasDrawer.drawImage(myImage); save(canvasDrawer.getAsBase64); }); });
  43. 43. almond.js
  44. 44. JS modules P2: Yes Old products: Yes Connect: Yes
  45. 45. “ Amazon: For every 100ms increase in load time of Amazon.com decreased sales by 1% Google: From 10 results in 0.4 seconds to to 30 results in 0.9 seconds decreased traffic and ad revenues by 20% Google: An extra 500ms in loading time resulted in 20% drop in traffic. Yahoo: 400ms slower page would see 5-9% more people leave before the page finished loading. ”
  46. 46. Gallery Hero Main Select Create Read Files Form Utils Render Meme
  47. 47. Gallery Hero Main Select Create Read Files Form Utils Render Meme
  48. 48. Async Resource Loading <web-resource key="create"> <resource type="download" name="create/main.js" location="create/main.js" /> <resource type="download" name="create/create.css" location="create/create.css" /> <resource type="download" name="create/create.js" location="create/create.soy" /> ... </web-resource>
  49. 49. Async Resource Loading require("gallery/main").onSelectCreate(function() { WRM.require([ "wr!com.atlassian.atlassian-meme-generator:create" ]).done(function() { showCreateView(); }); });
  50. 50. Async Resource Loading P2: Yes Old products: Yes Connect: Other libs
  51. 51. Beauty: Soy Pretty URLs
  52. 52. Interactivity: Pushstate Server and Client rendering Data JS modules Async resource loading
  53. 53. Sample App: http://bitbucket.org/jcreenaune/atlassian-memegenerator AUI Debugger: http://bit.ly/10DXYlG
  54. 54. Thank you!
  55. 55. Party Starts at 19.00! SkyLounge, Oosterdoksstraat 4, 11th Floor

×