diff --git a/docs/creating-a-package.md b/docs/creating-a-package.md index 75d47f5aa..167a73008 100644 --- a/docs/creating-a-package.md +++ b/docs/creating-a-package.md @@ -214,6 +214,19 @@ your grammar supports: ] ``` +## Bundle External Resources + +It's common to ship external resources like images and fonts in the package, to +make it easy to reference the resources in HTML or CSS, you can use the `atom` +protocol URLs to load resources in the package. + +The URLs should be in the format of +`atom://package-name/relative-path-to-package-of-resource`, for example, the +`atom://image-view/images/transparent-background.gif` would be equivablent to +`~/.atom/packages/image-view/images/transparent-background.gif`. + +You can also use the `atom` protocol URLs in themes. + ## Writing Tests Your package **should** have tests, and if they're placed in the _spec_ directory, diff --git a/package.json b/package.json index 1f904ffef..facbbdfaa 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "bugs": { "url": "https://github.com/atom/atom/issues" }, - "atomShellVersion": "0.4.5", + "atomShellVersion": "0.4.7", "dependencies": { "async": "0.2.6", "coffee-script": "1.6.2", diff --git a/spec/atom-protocol-handler-spec.coffee b/spec/atom-protocol-handler-spec.coffee new file mode 100644 index 000000000..218cfb810 --- /dev/null +++ b/spec/atom-protocol-handler-spec.coffee @@ -0,0 +1,15 @@ +$ = require 'jquery' + +describe '"atom" protocol URL', -> + it 'sends the file relative in the package as response', -> + called = false + callback = -> called = true + $.ajax + url: 'atom://async/package.json' + success: callback + # In old versions of jQuery, ajax calls to custom protocol would always + # be treated as error eventhough the browser thinks it's a success + # request. + error: callback + + waitsFor 'request to be done', -> called is true diff --git a/src/atom-application.coffee b/src/atom-application.coffee index 54f2fa92b..507baccfc 100644 --- a/src/atom-application.coffee +++ b/src/atom-application.coffee @@ -1,5 +1,6 @@ AtomWindow = require 'atom-window' ApplicationMenu = require 'application-menu' +AtomProtocolHandler = require 'atom-protocol-handler' BrowserWindow = require 'browser-window' Menu = require 'menu' autoUpdater = require 'auto-updater' @@ -45,6 +46,7 @@ class AtomApplication windows: null applicationMenu: null + atomProtocolHandler: null resourcePath: null version: null @@ -56,6 +58,7 @@ class AtomApplication @windows = [] @applicationMenu = new ApplicationMenu(@version, devMode) + @atomProtocolHandler = new AtomProtocolHandler(@resourcePath) @listenForArgumentsFromNewProcess() @setupJavaScriptArguments() diff --git a/src/atom-protocol-handler.coffee b/src/atom-protocol-handler.coffee new file mode 100644 index 000000000..d95bd30f1 --- /dev/null +++ b/src/atom-protocol-handler.coffee @@ -0,0 +1,27 @@ +app = require 'app' +fs = require 'fs' +path = require 'path' +protocol = require 'protocol' + +# Private: Handles requests with 'atom' protocol. +# +# It's created by {AtomApplication} upon instantiation, and is used to create a +# custom resource loader by adding the 'atom' custom protocol. +module.exports = +class AtomProtocolHandler + constructor: (@resourcePath) -> + @loadPaths = [ + path.join(@resourcePath, 'node_modules') + path.join(app.getHomeDir(), '.atom', 'packages') + ] + + @registerAtomProtocol() + + # Private: Creates the 'atom' custom protocol handler. + registerAtomProtocol: -> + protocol.registerProtocol 'atom', (request) => + relativePath = path.normalize(request.url.substr(7)) + for loadPath in @loadPaths + filePath = path.join(loadPath, relativePath) + break if fs.statSyncNoException(filePath)? + return new protocol.RequestFileJob(filePath)