├── README.md └── template ├── .gitignore ├── README.md ├── assets └── icon.png ├── package.json ├── resources ├── style.css ├── webview.html └── webview.js ├── sketch-assets └── icons.sketch ├── src ├── manifest.json └── my-command.js └── webpack.skpm.config.js /README.md: -------------------------------------------------------------------------------- 1 | # with-webview skpm template 2 | 3 | ## Documentation 4 | 5 | - This is a template for [skpm](https://github.com/skpm/skpm) using a webview. 6 | - [For skpm](https://github.com/skpm/skpm): General information about how to work with skpm, not specific to this template 7 | - [For Sketch plugin](http://developer.sketchapp.com): General information about sketch plugin developement 8 | 9 | ## Usage 10 | 11 | ``` bash 12 | $ npm install -g skpm 13 | $ skpm create my-plugin --template=skpm/with-webview 14 | $ cd my-plugin 15 | $ npm run watch 16 | ``` 17 | 18 | ### Fork It And Make Your Own 19 | 20 | You can fork this repo to create your own boilerplate, and use it with `skpm`: 21 | 22 | ``` bash 23 | skpm create my-plugin --template=username/repo 24 | ``` 25 | -------------------------------------------------------------------------------- /template/.gitignore: -------------------------------------------------------------------------------- 1 | # build artefacts 2 | {{ slug }}.sketchplugin 3 | 4 | # npm 5 | node_modules 6 | .npm 7 | npm-debug.log 8 | 9 | # mac 10 | .DS_Store 11 | 12 | # WebStorm 13 | .idea 14 | 15 | # sketch 16 | # sketch-assets 17 | -------------------------------------------------------------------------------- /template/README.md: -------------------------------------------------------------------------------- 1 | # {{ name }} 2 | 3 | ## Installation 4 | 5 | - [Download](../../releases/latest/download/{{ slug }}.sketchplugin.zip) the latest release of the plugin 6 | - Un-zip 7 | - Double-click on {{ slug }}.sketchplugin 8 | 9 | ## Development Guide 10 | 11 | _This plugin was created using `skpm`. For a detailed explanation on how things work, checkout the [skpm Readme](https://github.com/skpm/skpm/blob/master/README.md)._ 12 | 13 | ### Usage 14 | 15 | Install the dependencies 16 | 17 | ```bash 18 | npm install 19 | ``` 20 | 21 | Once the installation is done, you can run some commands inside the project folder: 22 | 23 | ```bash 24 | npm run build 25 | ``` 26 | 27 | To watch for changes: 28 | 29 | ```bash 30 | npm run watch 31 | ``` 32 | 33 | ### Custom Configuration 34 | 35 | #### Babel 36 | 37 | To customize Babel, you have two options: 38 | 39 | - You may create a [`.babelrc`](https://babeljs.io/docs/usage/babelrc) file in your project's root directory. Any settings you define here will overwrite matching config-keys within skpm preset. For example, if you pass a "presets" object, it will replace & reset all Babel presets that skpm defaults to. 40 | 41 | - If you'd like to modify or add to the existing Babel config, you must use a `webpack.skpm.config.js` file. Visit the [Webpack](#webpack) section for more info. 42 | 43 | #### Webpack 44 | 45 | To customize webpack create `webpack.skpm.config.js` file which exports function that will change webpack's config. 46 | 47 | ```js 48 | /** 49 | * Function that mutates original webpack config. 50 | * Supports asynchronous changes when promise is returned. 51 | * 52 | * @param {object} config - original webpack config. 53 | * @param {object} entry - entry property from webpack config 54 | * @param {boolean} entry.isPluginCommand - whether the config is for a plugin command or a resource 55 | **/ 56 | module.exports = function(config, entry) { 57 | /** you can change config here **/ 58 | }; 59 | ``` 60 | 61 | To use the polyfills or the mocks for certain Node.js globals and modules use the `node` property. 62 | 63 | Visit [the official documention](https://webpack.js.org/configuration/node/) for available options. 64 | 65 | ```js 66 | if(entry.isPluginCommand ){ 67 | config.node = { 68 | setImmediate: false 69 | } 70 | } else { 71 | config.node = false; 72 | } 73 | ``` 74 | 75 | ### Debugging 76 | 77 | To view the output of your `console.log`, you have a few different options: 78 | 79 | - Use the [`sketch-dev-tools`](https://github.com/skpm/sketch-dev-tools) 80 | - Open `Console.app` and look for the sketch logs 81 | - Look at the `~/Library/Logs/com.bohemiancoding.sketch3/Plugin Output.log` file 82 | 83 | Skpm provides a convenient way to do the latter: 84 | 85 | ```bash 86 | skpm log 87 | ``` 88 | 89 | The `-f` option causes `skpm log` to not stop when the end of logs is reached, but rather to wait for additional data to be appended to the input 90 | 91 | ### Publishing your plugin 92 | 93 | ```bash 94 | skpm publish 95 | ``` 96 | 97 | (where `bump` can be `patch`, `minor` or `major`) 98 | 99 | `skpm publish` will create a new release on your GitHub repository and create an appcast file in order for Sketch users to be notified of the update. 100 | 101 | You will need to specify a `repository` in the `package.json`: 102 | 103 | ```diff 104 | ... 105 | + "repository" : { 106 | + "type": "git", 107 | + "url": "git+https://github.com/ORG/NAME.git" 108 | + } 109 | ... 110 | ``` 111 | -------------------------------------------------------------------------------- /template/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skpm/with-webview/273446b7f65b669a93293f114395534495924c2a/template/assets/icon.png -------------------------------------------------------------------------------- /template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ slug }}", 3 | "version": "0.1.0", 4 | "engines": { 5 | "sketch": ">=3.0" 6 | }, 7 | "skpm": { 8 | "name": "{{ name }}", 9 | "manifest": "src/manifest.json", 10 | "main": "{{ slug }}.sketchplugin", 11 | "assets": [ 12 | "assets/**/*" 13 | ], 14 | "sketch-assets-file": "sketch-assets/icons.sketch" 15 | }, 16 | "scripts": { 17 | "build": "skpm-build", 18 | "watch": "skpm-build --watch", 19 | "start": "skpm-build --watch", 20 | "postinstall": "npm run build && skpm-link" 21 | }, 22 | "devDependencies": { 23 | "@skpm/builder": "^0.7.4", 24 | "@skpm/extract-loader": "^2.0.2", 25 | "css-loader": "^3.2.0", 26 | "html-loader": "^0.5.5" 27 | }, 28 | "resources": [ 29 | "resources/**/*.js" 30 | ], 31 | "dependencies": { 32 | "sketch-module-web-view": "^3.1.4" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /template/resources/style.css: -------------------------------------------------------------------------------- 1 | /* some default styles to make the view more native like */ 2 | 3 | html { 4 | box-sizing: border-box; 5 | background: transparent; 6 | 7 | /* Prevent the page to be scrollable */ 8 | overflow: hidden; 9 | 10 | /* Force the default cursor, even on text */ 11 | cursor: default; 12 | } 13 | 14 | *, *:before, *:after { 15 | box-sizing: inherit; 16 | margin: 0; 17 | padding: 0; 18 | position: relative; 19 | 20 | /* Prevent the content from being selectionable */ 21 | -webkit-user-select: none; 22 | user-select: none; 23 | } 24 | 25 | input, textarea { 26 | -webkit-user-select: auto; 27 | user-select: auto; 28 | } 29 | -------------------------------------------------------------------------------- /template/resources/webview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ name }} 6 | 7 | 8 | 9 | {{ name }} 10 | 11 |
12 | 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /template/resources/webview.js: -------------------------------------------------------------------------------- 1 | // disable the context menu (eg. the right click menu) to have a more native feel 2 | document.addEventListener('contextmenu', (e) => { 3 | e.preventDefault() 4 | }) 5 | 6 | // call the plugin from the webview 7 | document.getElementById('button').addEventListener('click', () => { 8 | window.postMessage('nativeLog', 'Called from the webview') 9 | }) 10 | 11 | // call the webview from the plugin 12 | window.setRandomNumber = (randomNumber) => { 13 | document.getElementById('answer').innerHTML = 'Random number from the plugin: ' + randomNumber 14 | } 15 | -------------------------------------------------------------------------------- /template/sketch-assets/icons.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skpm/with-webview/273446b7f65b669a93293f114395534495924c2a/template/sketch-assets/icons.sketch -------------------------------------------------------------------------------- /template/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "compatibleVersion": 3, 3 | "bundleVersion": 1, 4 | "commands": [ 5 | { 6 | "name": "my-command", 7 | "identifier": "{{ slug }}.my-command-identifier", 8 | "script": "./my-command.js", 9 | "handlers": { 10 | "run": "onRun", 11 | "actions": { 12 | "Shutdown": "onShutdown" 13 | } 14 | } 15 | } 16 | ], 17 | "menu": { 18 | "title": "{{ name }}", 19 | "items": ["{{ slug }}.my-command-identifier"] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /template/src/my-command.js: -------------------------------------------------------------------------------- 1 | import BrowserWindow from 'sketch-module-web-view' 2 | import { getWebview } from 'sketch-module-web-view/remote' 3 | import UI from 'sketch/ui' 4 | 5 | const webviewIdentifier = '{{ slug }}.webview' 6 | 7 | export default function () { 8 | const options = { 9 | identifier: webviewIdentifier, 10 | width: 240, 11 | height: 180, 12 | show: false 13 | } 14 | 15 | const browserWindow = new BrowserWindow(options) 16 | 17 | // only show the window when the page has loaded to avoid a white flash 18 | browserWindow.once('ready-to-show', () => { 19 | browserWindow.show() 20 | }) 21 | 22 | const webContents = browserWindow.webContents 23 | 24 | // print a message when the page loads 25 | webContents.on('did-finish-load', () => { 26 | UI.message('UI loaded!') 27 | }) 28 | 29 | // add a handler for a call from web content's javascript 30 | webContents.on('nativeLog', s => { 31 | UI.message(s) 32 | webContents 33 | .executeJavaScript(`setRandomNumber(${Math.random()})`) 34 | .catch(console.error) 35 | }) 36 | 37 | browserWindow.loadURL(require('../resources/webview.html')) 38 | } 39 | 40 | // When the plugin is shutdown by Sketch (for example when the user disable the plugin) 41 | // we need to close the webview if it's open 42 | export function onShutdown() { 43 | const existingWebview = getWebview(webviewIdentifier) 44 | if (existingWebview) { 45 | existingWebview.close() 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /template/webpack.skpm.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (config, entry) { 2 | config.node = entry.isPluginCommand ? false : { 3 | setImmediate: false 4 | }; 5 | config.module.rules.push({ 6 | test: /\.(html)$/, 7 | use: [{ 8 | loader: "@skpm/extract-loader", 9 | }, 10 | { 11 | loader: "html-loader", 12 | options: { 13 | attrs: [ 14 | 'img:src', 15 | 'link:href' 16 | ], 17 | interpolate: true, 18 | }, 19 | }, 20 | ] 21 | }) 22 | config.module.rules.push({ 23 | test: /\.(css)$/, 24 | use: [{ 25 | loader: "@skpm/extract-loader", 26 | }, 27 | { 28 | loader: "css-loader", 29 | }, 30 | ] 31 | }) 32 | } 33 | --------------------------------------------------------------------------------