PageRenderTime 24ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/0.1.0/innertube.js

https://github.com/ianli/innertube
JavaScript | 152 lines | 63 code | 16 blank | 73 comment | 14 complexity | 5ec9180e5a693c227624feb3d3071d0e MD5 | raw file
  1. /*!
  2. * Innertube Widgets API 0.1.0
  3. * http://ianli.github.com/innertube/
  4. *
  5. * Copyright 2011 Ian Li (http://ianli.com)
  6. * Innertube Widgets API is freely distributable under the MIT license.
  7. *
  8. * Requires the following Javascript libraries:
  9. * - [easyXDM](http://easyxdm.net/) for cross-domain messaging
  10. * - [Underscore.js](http://documentcloud.github.com/underscore/) for utility functions
  11. */
  12. // The semicolon prevents potential errors when minifying plugins together.
  13. // The function sandboxes the code.
  14. // Pass local reference to window for performance reasons.
  15. // Redefines undefined as it could have been tampered with.
  16. ;(function (window, undefined) {
  17. // Innertube.RPC
  18. // ===============================================
  19. // Innertube.RPC is the interface between widgets and the dashboard.
  20. // `localProperties` include methods that are called by the local RPC instance;
  21. // they cannot be called by remote entities.
  22. // On the other hand, `remoteProperties` are methods that are called by remote entities.
  23. var RPC = function (localProperties, remoteProperties) {
  24. // We use the variable self to represent this object
  25. // and to reduce confusion regarding what `this` refers to.
  26. var self = this,
  27. // Make copies of the arguments, because we'll be modifying them.
  28. localProps = _.clone(localProperties),
  29. remoteProps = _.clone(remoteProperties);
  30. // Assign default values to the local properties
  31. // if left unassigned.
  32. _.defaults(localProps, {
  33. // Called when easyXDM.Rpc is ready.
  34. // If left unassigned, do nothing.
  35. ready: function() {},
  36. // Called when a method doesn't exist.
  37. // If left unassigned, do nothing.
  38. methodMissing: function() {}
  39. });
  40. // Current version of the Innertube.RPC
  41. RPC.VERSION = '0.1.0';
  42. // Add a remote method that returns the version number of this RPC.
  43. // We assign it here, so that it cannot be overridden.
  44. remoteProps.version = function () {
  45. return RPC.VERSION;
  46. };
  47. // We use easyXDM.Rpc as a way to communicate
  48. // between the widget and the dashboard.
  49. var rpc = new easyXDM.Rpc({
  50. // This function is called when the RPC is ready.
  51. onReady: function() {
  52. if (_.isFunction(localProps.ready)) {
  53. localProps.ready.apply(self);
  54. }
  55. }
  56. },
  57. // Interface Configuration
  58. {
  59. local: {
  60. widget: function(method, args, successFn, errorFn) {
  61. if (_.isFunction(remoteProps[method])) {
  62. var returnValue = remoteProps[method].apply(self, args);
  63. if (!_.isUndefined(returnValue)) {
  64. return returnValue;
  65. }
  66. } else {
  67. // No method exists, call the `methodMissing` method.
  68. if (_.isFunction(localProps.methodMissing)) {
  69. localProps.methodMissing.apply(self);
  70. } else {
  71. // Otherwise, fail silently.
  72. }
  73. }
  74. }
  75. },
  76. remote: {
  77. // Invoke methods on the dashboard.
  78. dashboard: {}
  79. }
  80. }
  81. );
  82. // Sends messages to the Innertube Dashboard.
  83. // `method` is the method to call on the Innertube Dashboard.
  84. // The remaining arguments are passed as arguments to the method
  85. // in the Innertube Dashboard.
  86. //
  87. // There are multiple approaches to call methods on the dashboard.
  88. // 1. Methods with no arguments.
  89. // dashboard(method);
  90. //
  91. // 2. Methods with arguments.
  92. // dashboard(method, arg1, arg2, arg3, ...)
  93. //
  94. // 3. Methods with no arguments and returns a value.
  95. // dashboard(method, {
  96. // success: function(returnValue) {
  97. // ...
  98. // }
  99. // });
  100. //
  101. // 4. Methods with arguments and returns a value.
  102. // dashboard(method, arg1, arg2, ..., {
  103. // success: function(returnValue) {
  104. // ...
  105. // }
  106. // });
  107. self.dashboard = function (method) {
  108. var args = Array.prototype.slice.call(arguments, 1);
  109. if (args.length == 0) {
  110. // Approach #1
  111. // Must send an empty array as argument
  112. // to match signature of dashboard(method, args)
  113. rpc.dashboard(method, []);
  114. } else {
  115. // Check if the last argument is an object
  116. // `success` and `error` functions.
  117. var lastArg = args[args.length - 1];
  118. if (lastArg.success || lastArg.error) {
  119. // Remove the last element of the arguments list.
  120. args.pop();
  121. var success = lastArg.success || function () {};
  122. var error = lastArg.error || function() {};
  123. // Approach #3 and #4
  124. rpc.dashboard(method, args, success, error);
  125. } else {
  126. // Approach #2
  127. rpc.dashboard(method, args);
  128. }
  129. }
  130. return self;
  131. };
  132. }
  133. window.Innertube = {
  134. RPC: RPC
  135. }
  136. })(window);