Skip to content

Commit

Permalink
feature(api): identify path of sass.worker.js via `document.currentSc…
Browse files Browse the repository at this point in the history
…ript` - #32
  • Loading branch information
rodneyrehm committed May 18, 2015
1 parent 5c34a5a commit 54b8082
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
30 changes: 25 additions & 5 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,35 @@ Sass.js comes in two pieces: `sass.js` being the API available to the browser, `
```html
<script src="dist/sass.js"></script>
<script>
// initialize sass.js, specifying where it can find the worker,
// url is relative to document.URL
var sass = new Sass('dist/sass.worker.js');
var scss = '$someVar: 123px; .some-selector { width: $someVar; }';
sass.compile(scss, function(result) {
console.log(result);
});
</script>
```

If you load `sass.js` by other means than then `<script>` example above, it cannot find the URL of `dist/sass.worker.js` by itself. In this case you need to tell Sass where to find the worker first:

```js
define(function defineSassModule(require) {
// load Sass.js
var Sass = require('path/to/sass.js');

// tell Sass.js where it can find the worker,
// url is relative to document.URL - i.e. outside of whatever
// Require or Browserify et al do for you
Sass.setWorkerUrl('dist/sass.worker.js');

// initialize a Sass instance
var sass = new Sass();

var scss = '$someVar: 123px; .some-selector { width: $someVar; }';
sass.compile(scss, function(result) {
console.log(result);
});
});
```

### Synchronous API (browser)

It is possible - but *not recommended* to use Sass.js in the main EventLoop instead of using a Worker, by running [`sass.sync.html`](sass.sync.html). Contrary to the worker API, the synchronous API does not allow concurrency, which is why it exposes a "singleton" instance:
Expand Down Expand Up @@ -508,15 +526,17 @@ LIBSASS_VERSION="3.1.0"

### master (will become 0.9.0) ###

**NOTE:** This release contains one breaking change!
**NOTE:** This release contains breaking changes!

* upgrading to [libsass 3.2.4](https://github.com/sass/libsass/releases/tag/3.2.4)
* fixing worker API to avoid throwing `DataCloneError` because `postMessage` can't handle `Error` instances
* improving worker API to find `sass.worker.js` itself when loaded through simple `<script>` element - ([Issue #32](https://github.com/medialize/sass.js/issues/32))
* improving worker API to allow multiple *parallel* workers to be initialized - **Breaking Change**
* improving `Sass.compile()` to queue multiple invocations for serialized execution rather than throwing an error
* adding `sass.destroy()` to terminate a worker and free its resources
* adding `Sass.setWorkerUrl()` to define the path of the worker before a Sass instance is created


#### Breaking Changes

* The worker API used to be initialized with `Sass.initialize('path/to/sass.worker.js')`, but as of v0.9.0 requires proper instantiation: `var sass = new Sass('path/to/sass.worker.js')`.
Expand Down
12 changes: 10 additions & 2 deletions sass.worker.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ <h1>Sass.js Worker Console</h1>
<p>This document loads the <em>worker</em> sass.js. Please open your browser's DevTools to use the API.</p>

<h2>Try the following example:</h2>
<pre>var sass = new Sass('dist/sass.worker.js');
<pre>// when loading the worker api via script[src$="/sass.js"] it's a safe bet the worker
// will be found relative to that file. In any other case you'd have to define where
// the worker is located before initializing Sass:
// Sass.setWorkerUrl('dist/sass.worker.js');
var sass = new Sass();

sass.writeFile('testfile.scss', '@import "sub/deeptest";\n.testfile { content: "loaded"; }', function() {
console.log('wrote "testfile.scss"');
Expand All @@ -26,7 +30,11 @@ <h2>Try the following example:</h2>

<script src="dist/sass.js"></script>
<script>
var sass = new Sass('dist/sass.worker.js');
// when loading the worker api via script[src$="/sass.js"] it's a safe bet the worker
// will be found relative to that file. In any other case you'd have to define where
// the worker is located before initializing Sass:
// Sass.setWorkerUrl('dist/sass.worker.js');
var sass = new Sass();

sass.writeFile('testfile.scss', '@import "sub/deeptest";\n.testfile { content: "loaded"; }', function() {
console.log('wrote "testfile.scss"');
Expand Down
24 changes: 23 additions & 1 deletion src/sass.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@

function Sass(workerUrl) {
if (!workerUrl && !globalWorkerUrl) {
throw new Error('Sass needs to be initialized with the URL of sass.worker.js');
throw new Error(
'Sass needs to be initialized with the URL of sass.worker.js - '
+ 'either via Sass.setWorkerUrl(url) or by new Sass(url)'
);
}

if (!globalWorkerUrl) {
Expand Down Expand Up @@ -144,5 +147,24 @@
};
});

// automatically set the workerUrl in case we're loaded by a simple
// <script src="path/to/sass.js"></script>
// see https://github.com/medialize/sass.js/pull/32#issuecomment-103142214
// we can only run this test in the browser,
// so make sure we actually have a DOM to work with
if (typeof document !== 'undefined' && document.getElementsByTagName) {
// http://www.2ality.com/2014/05/current-script.html
var currentScript = document.currentScript || (function() {
var scripts = document.getElementsByTagName('script');
return scripts[scripts.length - 1];
})();

var defaultWorkerUrl = currentScript && currentScript.src;
// make sure we're not running in some concatenated thing
if (defaultWorkerUrl && defaultWorkerUrl.slice(-8) === '/sass.js') {
Sass.setWorkerUrl(defaultWorkerUrl.slice(0, -8) + '/sass.worker.js');
}
}

return Sass;
}));

0 comments on commit 54b8082

Please sign in to comment.