├── .babelrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── dist ├── ng-helper.js ├── sb.js └── stories.js ├── docs └── sb-demo.gif ├── gulpfile.babel.js ├── helpers └── ng.js ├── karma.conf.js ├── package.json ├── sb.js ├── spec.bundle.js ├── src ├── app │ ├── components │ │ └── components.js │ ├── index.js │ └── style.less ├── helpers │ └── angular │ │ ├── helper.compile.js │ │ ├── helper.controller.js │ │ ├── helper.js │ │ └── interceptor.service.js ├── index.html ├── preview.html ├── sb.d.ts ├── sb │ ├── app.module.js │ ├── components │ │ ├── components.module.js │ │ ├── interceptor │ │ │ ├── interceptor.component.js │ │ │ ├── interceptor.controller.js │ │ │ ├── interceptor.html │ │ │ └── interceptor.less │ │ ├── markdown │ │ │ ├── markdown.component.js │ │ │ ├── markdown.controller.js │ │ │ ├── markdown.html │ │ │ └── markdown.less │ │ ├── model │ │ │ ├── model.component.js │ │ │ ├── model.controller.js │ │ │ ├── model.html │ │ │ └── model.less │ │ ├── preview │ │ │ ├── devices.js │ │ │ ├── preview.component.js │ │ │ ├── preview.controller.js │ │ │ ├── preview.html │ │ │ └── preview.less │ │ ├── storyList │ │ │ ├── storyList.component.js │ │ │ ├── storyList.controller.js │ │ │ ├── storyList.html │ │ │ └── storyList.less │ │ └── template │ │ │ ├── template.component.js │ │ │ ├── template.controller.js │ │ │ ├── template.less │ │ │ └── template.partial.html │ ├── core │ │ ├── core.module.js │ │ └── core.route.js │ ├── directives │ │ └── directives.module.js │ ├── index.js │ ├── modules │ │ ├── modules.module.js │ │ └── storybook │ │ │ ├── helper.compile.js │ │ │ ├── storybook.component.js │ │ │ ├── storybook.controller.js │ │ │ ├── storybook.html │ │ │ ├── storybook.js │ │ │ └── storybook.less │ ├── services │ │ ├── services.module.js │ │ └── store.service.js │ └── styles │ │ ├── app.less │ │ └── highlight.less ├── stories-api.js └── stories │ └── index.js ├── stories.js ├── webpack.config.js ├── webpack.dev.config.js └── webpack.dist.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime"], 3 | "presets": ["es2015", "stage-0"] 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .tmp 3 | .git 4 | node_modules 5 | .settings 6 | *.log 7 | .idea 8 | 9 | src/components 10 | src/stories 11 | 12 | dist/app.js 13 | 14 | .editorconfig 15 | 16 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .tmp 3 | .git 4 | node_modules 5 | .settings 6 | *.log 7 | .idea 8 | src 9 | dist/app.js 10 | .editorconfig 11 | webpack* 12 | spec.bundle.js 13 | karma.conf.js 14 | gulpfile.babel.js -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | cache: 4 | directories: 5 | - node_modules 6 | notifications: 7 | email: false 8 | node_js: 9 | - '4' 10 | before_install: 11 | - npm i -g npm@^2.0.0 12 | before_script: 13 | - npm prune 14 | after_success: 15 | - npm run semantic-release 16 | branches: 17 | except: 18 | - /^v\d+\.\d+\.\d+$/ 19 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | If you find a bug (and you don’t know how to fix it), have trouble following the documentation or have a question or ideas how to improve SB – create an issue! 2 | If you’re able to patch the bug or add the feature yourself – fantastic, make a pull request with the code! 3 | 4 | Available gulp tasks: 5 | 6 | # run dev server with demo data 7 | gulp serve 8 | 9 | # create new build 10 | gulp build 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Dubovetzky Dmitriy. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SB [![npm version](https://badge.fury.io/js/ui-storybook.svg)](https://badge.fury.io/js/ui-storybook) [![Gitter Chat](https://badges.gitter.im/owner/repo.png)](https://gitter.im/ui-sb/Lobby) 2 | 3 | 4 | SB is the environment for developers that allow to easily develop and support UI components with any framework. With it, you can visualize different states of your UI components and develop them interactively. 5 | 6 | ![SB demo image](docs/sb-demo.gif) 7 | 8 | SB run your app in sandbox, so you can develop without warning about any specific dependency. 9 | 10 | ## Demo 11 | [Material cards](https://ui-storybook.github.io/sb-angular-material-cards-demo/#/?split=true) — [Source](https://github.com/ui-storybook/sb-angular-material-cards-demo) 12 | 13 | ## What is supported now? 14 | Angular 1 — [API](#angular-usage) 15 | React — [API](#react-usage) 16 | NG2 — Comming soon 17 | Aurelia — Comming soon 18 | Vue.js — Comming soon 19 | 20 | Basically, SB was designed for support any frameworks and libraries. All you components run in isolated scope with that version of framework or library that you need. 21 | For now SB support Angular 1.x and React. Support for NG2, Aurelia and Vue.js coming very soon. 22 | 23 | 24 | ## Getting started 25 | Fastest way to add SB to your project is to use [sb-cli](https://github.com/ui-storybook/sb-cli): 26 | 27 | ```bash 28 | # Installation 29 | npm i -g sb-cli 30 | 31 | # Then in your project folder run 32 | sb-create 33 | ``` 34 | 35 | This will create `sb` folder with all dependencies based on project type. 36 | 37 | Add the `-Y` or `--use-yarn` flag if your project uses yarn instead of npm as package manager. 38 | 39 | ## Usage 40 | #### Available commands 41 | ```bash 42 | # run sb server 43 | npm run sb 44 | 45 | # build sb with your project 46 | npm run sb-build 47 | 48 | # create new build and publish it to GitHub Pages 49 | npm run sb-publish 50 | ``` 51 | 52 | ### Angular usage 53 | First you need to import your main project module to `sb/index.js` 54 | 55 | ```js 56 | // Import you app 57 | import '../path/to/your/module'; 58 | 59 | // And inject it here 60 | const mainModule = angular.module('sb', [ 61 | 'helper', 62 | 'youAppName' 63 | ]); 64 | 65 | ``` 66 | 67 | Write your stories 68 | SB provides simple api for you: 69 | 70 | ```js 71 | // File sb/stories/index.js 72 | 73 | // Create a new section (like page) 74 | let buttons = sb.section('Buttons'); 75 | 76 | // Then you can add new story and states to section 77 | buttons.story('Simple buttons') 78 | 79 | // add method create new state for story 80 | // first param take title of state 81 | // second take html template that need to render 82 | // and third take object which need to load to component scope 83 | .add('Main button', '', { 84 | title: 'Hello from SB' 85 | }) 86 | .add('Success button', '', { 87 | someOtherTitle: 'You successfully build first story' 88 | }); 89 | 90 | ``` 91 | Also you can use `sb.mock` method for stote your mocks and then use in stories passing mock name instead of object: 92 | ```js 93 | sb.mock('week', { 94 | sunday: 'Sunday', 95 | monday: 'Monday', 96 | tuesday: 'Tuesday', 97 | wednesday: 'Wednesday', 98 | thursday: 'Thursday', 99 | friday: 'Friday', 100 | saturday: 'Saturday' 101 | }); 102 | 103 | let calendar = sb.section('Week'); 104 | calendar.story('Days of the week') 105 | .add('Sunday', '

{{ vm.sunday }}

', 'week') 106 | .add('Monday', '

{{ vm.monday }}

', 'week') 107 | .add('Tuesday', '

{{ vm.tuesday }}

', 'week') 108 | .add('Wednesday', '

{{ vm.wednesday }}

', 'week') 109 | .add('Thursday', '

{{ vm.thursday }}

', 'week') 110 | .add('Friday', '

{{ vm.friday }}

', 'week') 111 | .add('Saturday', '

{{ vm.saturday }}

', 'week'); 112 | ``` 113 | 114 | 115 | Than simply run `npm run sb` — this will load server with hotreload and run SB with your application. 116 | 117 | ### React usage 118 | First you need to import your React components in `sb/index.js` file 119 | 120 | ```js 121 | // Example from demo application 122 | import { Welcome } from './welcome/welcome'; 123 | ``` 124 | 125 | The write your stories 126 | SB provides simple api for you: 127 | 128 | ```js 129 | // File sb/stories/index.js 130 | 131 | // You need import your commponent here too 132 | import { Welcome } from './../welcome/welcome'; 133 | 134 | // Create a new section (like page) 135 | let overview = sb.section('Welcome section'); 136 | 137 | // Then you can add new story and states to section 138 | // add method create new state for story 139 | // first param take title of state 140 | // second take function that return Raact component 141 | overview.story('SB demo component') 142 | .add('Hello messages', () => ()); 143 | ``` 144 | 145 | Than simply run `npm run sb` — this will load server with hotreload and run SB with your application. 146 | 147 | ### Components Documentation 148 | SB can show documentation or notes for your components from `.md` files. 149 | 150 | ```js 151 | 152 | // Import your md file 153 | import docs from './docs.md'; 154 | 155 | let calendar = sb.section('Week'); 156 | 157 | // And pass with 4th param to story 158 | calendar.story('Days of the week') 159 | .add('Sunday', '

{{ vm.sunday }}

', {}, docs) 160 | ``` 161 | 162 | ### Configuration 163 | SB use Webpack to build everything. If you need to change or update build process go to `sb/.webpack` folder: 164 | `server.js` include configuration for browser-sync and webpack HMR. 165 | `loaders.js` include all loaders. 166 | `webpack.dev.babel.js` include dev build configuration. 167 | `webpack.build.babel.js` include production build configuration. 168 | 169 | ## Contributing 170 | 171 | If you find a bug (and you don’t know how to fix it), have trouble following the documentation or have a question or ideas how to improve SB – create an issue! 172 | If you’re able to patch the bug or add the feature yourself – fantastic, make a pull request with the code! 173 | 174 | Available gulp tasks: 175 | ```bash 176 | 177 | # run dev server with demo data 178 | gulp serve 179 | 180 | # create new build 181 | gulp build 182 | 183 | ``` 184 | -------------------------------------------------------------------------------- /dist/ng-helper.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) 10 | /******/ return installedModules[moduleId].exports; 11 | 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ exports: {}, 15 | /******/ id: moduleId, 16 | /******/ loaded: false 17 | /******/ }; 18 | 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | 22 | /******/ // Flag the module as loaded 23 | /******/ module.loaded = true; 24 | 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | 29 | 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | 36 | /******/ // __webpack_public_path__ 37 | /******/ __webpack_require__.p = ""; 38 | 39 | /******/ // Load entry module and return exports 40 | /******/ return __webpack_require__(0); 41 | /******/ }) 42 | /************************************************************************/ 43 | /******/ ({ 44 | 45 | /***/ 0: 46 | /***/ function(module, exports, __webpack_require__) { 47 | 48 | module.exports = __webpack_require__(306); 49 | 50 | 51 | /***/ }, 52 | 53 | /***/ 306: 54 | /***/ function(module, exports, __webpack_require__) { 55 | 56 | 'use strict'; 57 | 58 | Object.defineProperty(exports, "__esModule", { 59 | value: true 60 | }); 61 | 62 | __webpack_require__(307); 63 | 64 | var _helper = __webpack_require__(309); 65 | 66 | var _helper2 = _interopRequireDefault(_helper); 67 | 68 | var _helper3 = __webpack_require__(330); 69 | 70 | var _helper4 = _interopRequireDefault(_helper3); 71 | 72 | var _interceptor = __webpack_require__(331); 73 | 74 | var _interceptor2 = _interopRequireDefault(_interceptor); 75 | 76 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 77 | 78 | var _module = angular.module('helper', ['ngSanitize']); 79 | 80 | _module.service('SBInterceptor', _interceptor2.default); 81 | 82 | _module.directive('compile', _helper4.default); 83 | 84 | _module.component('previewHelper', { 85 | controller: _helper2.default, 86 | template: '
', 87 | controllerAs: 'vm' 88 | }); 89 | 90 | exports.default = _module.name; 91 | 92 | /***/ }, 93 | 94 | /***/ 307: 95 | /***/ function(module, exports, __webpack_require__) { 96 | 97 | __webpack_require__(308); 98 | module.exports = 'ngSanitize'; 99 | 100 | 101 | /***/ }, 102 | 103 | /***/ 308: 104 | /***/ function(module, exports) { 105 | 106 | /** 107 | * @license AngularJS v1.5.11 108 | * (c) 2010-2017 Google, Inc. http://angularjs.org 109 | * License: MIT 110 | */ 111 | (function(window, angular) {'use strict'; 112 | 113 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 114 | * Any commits to this file should be reviewed with security in mind. * 115 | * Changes to this file can potentially create security vulnerabilities. * 116 | * An approval from 2 Core members with history of modifying * 117 | * this file is required. * 118 | * * 119 | * Does the change somehow allow for arbitrary javascript to be executed? * 120 | * Or allows for someone to change the prototype of built-in objects? * 121 | * Or gives undesired access to variables likes document or window? * 122 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 123 | 124 | var $sanitizeMinErr = angular.$$minErr('$sanitize'); 125 | var bind; 126 | var extend; 127 | var forEach; 128 | var isDefined; 129 | var lowercase; 130 | var noop; 131 | var htmlParser; 132 | var htmlSanitizeWriter; 133 | 134 | /** 135 | * @ngdoc module 136 | * @name ngSanitize 137 | * @description 138 | * 139 | * # ngSanitize 140 | * 141 | * The `ngSanitize` module provides functionality to sanitize HTML. 142 | * 143 | * 144 | *
145 | * 146 | * See {@link ngSanitize.$sanitize `$sanitize`} for usage. 147 | */ 148 | 149 | /** 150 | * @ngdoc service 151 | * @name $sanitize 152 | * @kind function 153 | * 154 | * @description 155 | * Sanitizes an html string by stripping all potentially dangerous tokens. 156 | * 157 | * The input is sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are 158 | * then serialized back to properly escaped html string. This means that no unsafe input can make 159 | * it into the returned string. 160 | * 161 | * The whitelist for URL sanitization of attribute values is configured using the functions 162 | * `aHrefSanitizationWhitelist` and `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider 163 | * `$compileProvider`}. 164 | * 165 | * The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}. 166 | * 167 | * @param {string} html HTML input. 168 | * @returns {string} Sanitized HTML. 169 | * 170 | * @example 171 | 172 | 173 | 185 |
186 | Snippet: 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 |
DirectiveHowSourceRendered
ng-bind-htmlAutomatically uses $sanitize
<div ng-bind-html="snippet">
</div>
ng-bind-htmlBypass $sanitize by explicitly trusting the dangerous value 204 |
<div ng-bind-html="deliberatelyTrustDangerousSnippet()">
 205 | 	</div>
206 |
ng-bindAutomatically escapes
<div ng-bind="snippet">
</div>
216 |
217 |
218 | 219 | it('should sanitize the html snippet by default', function() { 220 | expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')). 221 | toBe('

an html\nclick here\nsnippet

'); 222 | }); 223 | 224 | it('should inline raw snippet if bound to a trusted value', function() { 225 | expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')). 226 | toBe("

an html\n" + 227 | "click here\n" + 228 | "snippet

"); 229 | }); 230 | 231 | it('should escape snippet without any filter', function() { 232 | expect(element(by.css('#bind-default div')).getAttribute('innerHTML')). 233 | toBe("<p style=\"color:blue\">an html\n" + 234 | "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + 235 | "snippet</p>"); 236 | }); 237 | 238 | it('should update', function() { 239 | element(by.model('snippet')).clear(); 240 | element(by.model('snippet')).sendKeys('new text'); 241 | expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')). 242 | toBe('new text'); 243 | expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')).toBe( 244 | 'new text'); 245 | expect(element(by.css('#bind-default div')).getAttribute('innerHTML')).toBe( 246 | "new <b onclick=\"alert(1)\">text</b>"); 247 | }); 248 |
249 |
250 | */ 251 | 252 | 253 | /** 254 | * @ngdoc provider 255 | * @name $sanitizeProvider 256 | * @this 257 | * 258 | * @description 259 | * Creates and configures {@link $sanitize} instance. 260 | */ 261 | function $SanitizeProvider() { 262 | var svgEnabled = false; 263 | 264 | this.$get = ['$$sanitizeUri', function($$sanitizeUri) { 265 | if (svgEnabled) { 266 | extend(validElements, svgElements); 267 | } 268 | return function(html) { 269 | var buf = []; 270 | htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) { 271 | return !/^unsafe:/.test($$sanitizeUri(uri, isImage)); 272 | })); 273 | return buf.join(''); 274 | }; 275 | }]; 276 | 277 | 278 | /** 279 | * @ngdoc method 280 | * @name $sanitizeProvider#enableSvg 281 | * @kind function 282 | * 283 | * @description 284 | * Enables a subset of svg to be supported by the sanitizer. 285 | * 286 | *
287 | *

By enabling this setting without taking other precautions, you might expose your 288 | * application to click-hijacking attacks. In these attacks, sanitized svg elements could be positioned 289 | * outside of the containing element and be rendered over other elements on the page (e.g. a login 290 | * link). Such behavior can then result in phishing incidents.

291 | * 292 | *

To protect against these, explicitly setup `overflow: hidden` css rule for all potential svg 293 | * tags within the sanitized content:

294 | * 295 | *
296 | * 297 | *

 298 | 	   *   .rootOfTheIncludedContent svg {
 299 | 	   *     overflow: hidden !important;
 300 | 	   *   }
 301 | 	   *   
302 | *
303 | * 304 | * @param {boolean=} flag Enable or disable SVG support in the sanitizer. 305 | * @returns {boolean|ng.$sanitizeProvider} Returns the currently configured value if called 306 | * without an argument or self for chaining otherwise. 307 | */ 308 | this.enableSvg = function(enableSvg) { 309 | if (isDefined(enableSvg)) { 310 | svgEnabled = enableSvg; 311 | return this; 312 | } else { 313 | return svgEnabled; 314 | } 315 | }; 316 | 317 | ////////////////////////////////////////////////////////////////////////////////////////////////// 318 | // Private stuff 319 | ////////////////////////////////////////////////////////////////////////////////////////////////// 320 | 321 | bind = angular.bind; 322 | extend = angular.extend; 323 | forEach = angular.forEach; 324 | isDefined = angular.isDefined; 325 | lowercase = angular.lowercase; 326 | noop = angular.noop; 327 | 328 | htmlParser = htmlParserImpl; 329 | htmlSanitizeWriter = htmlSanitizeWriterImpl; 330 | 331 | // Regular Expressions for parsing tags and attributes 332 | var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 333 | // Match everything outside of normal chars and " (quote character) 334 | NON_ALPHANUMERIC_REGEXP = /([^#-~ |!])/g; 335 | 336 | 337 | // Good source of info about elements and attributes 338 | // http://dev.w3.org/html5/spec/Overview.html#semantics 339 | // http://simon.html5.org/html-elements 340 | 341 | // Safe Void Elements - HTML5 342 | // http://dev.w3.org/html5/spec/Overview.html#void-elements 343 | var voidElements = toMap('area,br,col,hr,img,wbr'); 344 | 345 | // Elements that you can, intentionally, leave open (and which close themselves) 346 | // http://dev.w3.org/html5/spec/Overview.html#optional-tags 347 | var optionalEndTagBlockElements = toMap('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr'), 348 | optionalEndTagInlineElements = toMap('rp,rt'), 349 | optionalEndTagElements = extend({}, 350 | optionalEndTagInlineElements, 351 | optionalEndTagBlockElements); 352 | 353 | // Safe Block Elements - HTML5 354 | var blockElements = extend({}, optionalEndTagBlockElements, toMap('address,article,' + 355 | 'aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' + 356 | 'h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul')); 357 | 358 | // Inline Elements - HTML5 359 | var inlineElements = extend({}, optionalEndTagInlineElements, toMap('a,abbr,acronym,b,' + 360 | 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,' + 361 | 'samp,small,span,strike,strong,sub,sup,time,tt,u,var')); 362 | 363 | // SVG Elements 364 | // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements 365 | // Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted. 366 | // They can potentially allow for arbitrary javascript to be executed. See #11290 367 | var svgElements = toMap('circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' + 368 | 'hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,' + 369 | 'radialGradient,rect,stop,svg,switch,text,title,tspan'); 370 | 371 | // Blocked Elements (will be stripped) 372 | var blockedElements = toMap('script,style'); 373 | 374 | var validElements = extend({}, 375 | voidElements, 376 | blockElements, 377 | inlineElements, 378 | optionalEndTagElements); 379 | 380 | //Attributes that have href and hence need to be sanitized 381 | var uriAttrs = toMap('background,cite,href,longdesc,src,xlink:href'); 382 | 383 | var htmlAttrs = toMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' + 384 | 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' + 385 | 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' + 386 | 'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' + 387 | 'valign,value,vspace,width'); 388 | 389 | // SVG attributes (without "id" and "name" attributes) 390 | // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes 391 | var svgAttrs = toMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' + 392 | 'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' + 393 | 'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' + 394 | 'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' + 395 | 'height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,' + 396 | 'marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,' + 397 | 'max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,' + 398 | 'path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,' + 399 | 'requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,' + 400 | 'stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,' + 401 | 'stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,' + 402 | 'stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,' + 403 | 'underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,' + 404 | 'width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,' + 405 | 'xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan', true); 406 | 407 | var validAttrs = extend({}, 408 | uriAttrs, 409 | svgAttrs, 410 | htmlAttrs); 411 | 412 | function toMap(str, lowercaseKeys) { 413 | var obj = {}, items = str.split(','), i; 414 | for (i = 0; i < items.length; i++) { 415 | obj[lowercaseKeys ? lowercase(items[i]) : items[i]] = true; 416 | } 417 | return obj; 418 | } 419 | 420 | var inertBodyElement; 421 | (function(window) { 422 | var doc; 423 | if (window.document && window.document.implementation) { 424 | doc = window.document.implementation.createHTMLDocument('inert'); 425 | } else { 426 | throw $sanitizeMinErr('noinert', 'Can\'t create an inert html document'); 427 | } 428 | var docElement = doc.documentElement || doc.getDocumentElement(); 429 | var bodyElements = docElement.getElementsByTagName('body'); 430 | 431 | // usually there should be only one body element in the document, but IE doesn't have any, so we need to create one 432 | if (bodyElements.length === 1) { 433 | inertBodyElement = bodyElements[0]; 434 | } else { 435 | var html = doc.createElement('html'); 436 | inertBodyElement = doc.createElement('body'); 437 | html.appendChild(inertBodyElement); 438 | doc.appendChild(html); 439 | } 440 | })(window); 441 | 442 | /** 443 | * @example 444 | * htmlParser(htmlString, { 445 | * start: function(tag, attrs) {}, 446 | * end: function(tag) {}, 447 | * chars: function(text) {}, 448 | * comment: function(text) {} 449 | * }); 450 | * 451 | * @param {string} html string 452 | * @param {object} handler 453 | */ 454 | function htmlParserImpl(html, handler) { 455 | if (html === null || html === undefined) { 456 | html = ''; 457 | } else if (typeof html !== 'string') { 458 | html = '' + html; 459 | } 460 | inertBodyElement.innerHTML = html; 461 | 462 | //mXSS protection 463 | var mXSSAttempts = 5; 464 | do { 465 | if (mXSSAttempts === 0) { 466 | throw $sanitizeMinErr('uinput', 'Failed to sanitize html because the input is unstable'); 467 | } 468 | mXSSAttempts--; 469 | 470 | // strip custom-namespaced attributes on IE<=11 471 | if (window.document.documentMode) { 472 | stripCustomNsAttrs(inertBodyElement); 473 | } 474 | html = inertBodyElement.innerHTML; //trigger mXSS 475 | inertBodyElement.innerHTML = html; 476 | } while (html !== inertBodyElement.innerHTML); 477 | 478 | var node = inertBodyElement.firstChild; 479 | while (node) { 480 | switch (node.nodeType) { 481 | case 1: // ELEMENT_NODE 482 | handler.start(node.nodeName.toLowerCase(), attrToMap(node.attributes)); 483 | break; 484 | case 3: // TEXT NODE 485 | handler.chars(node.textContent); 486 | break; 487 | } 488 | 489 | var nextNode; 490 | if (!(nextNode = node.firstChild)) { 491 | if (node.nodeType === 1) { 492 | handler.end(node.nodeName.toLowerCase()); 493 | } 494 | nextNode = node.nextSibling; 495 | if (!nextNode) { 496 | while (nextNode == null) { 497 | node = node.parentNode; 498 | if (node === inertBodyElement) break; 499 | nextNode = node.nextSibling; 500 | if (node.nodeType === 1) { 501 | handler.end(node.nodeName.toLowerCase()); 502 | } 503 | } 504 | } 505 | } 506 | node = nextNode; 507 | } 508 | 509 | while ((node = inertBodyElement.firstChild)) { 510 | inertBodyElement.removeChild(node); 511 | } 512 | } 513 | 514 | function attrToMap(attrs) { 515 | var map = {}; 516 | for (var i = 0, ii = attrs.length; i < ii; i++) { 517 | var attr = attrs[i]; 518 | map[attr.name] = attr.value; 519 | } 520 | return map; 521 | } 522 | 523 | 524 | /** 525 | * Escapes all potentially dangerous characters, so that the 526 | * resulting string can be safely inserted into attribute or 527 | * element text. 528 | * @param value 529 | * @returns {string} escaped text 530 | */ 531 | function encodeEntities(value) { 532 | return value. 533 | replace(/&/g, '&'). 534 | replace(SURROGATE_PAIR_REGEXP, function(value) { 535 | var hi = value.charCodeAt(0); 536 | var low = value.charCodeAt(1); 537 | return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';'; 538 | }). 539 | replace(NON_ALPHANUMERIC_REGEXP, function(value) { 540 | return '&#' + value.charCodeAt(0) + ';'; 541 | }). 542 | replace(//g, '>'); 544 | } 545 | 546 | /** 547 | * create an HTML/XML writer which writes to buffer 548 | * @param {Array} buf use buf.join('') to get out sanitized html string 549 | * @returns {object} in the form of { 550 | * start: function(tag, attrs) {}, 551 | * end: function(tag) {}, 552 | * chars: function(text) {}, 553 | * comment: function(text) {} 554 | * } 555 | */ 556 | function htmlSanitizeWriterImpl(buf, uriValidator) { 557 | var ignoreCurrentElement = false; 558 | var out = bind(buf, buf.push); 559 | return { 560 | start: function(tag, attrs) { 561 | tag = lowercase(tag); 562 | if (!ignoreCurrentElement && blockedElements[tag]) { 563 | ignoreCurrentElement = tag; 564 | } 565 | if (!ignoreCurrentElement && validElements[tag] === true) { 566 | out('<'); 567 | out(tag); 568 | forEach(attrs, function(value, key) { 569 | var lkey = lowercase(key); 570 | var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background'); 571 | if (validAttrs[lkey] === true && 572 | (uriAttrs[lkey] !== true || uriValidator(value, isImage))) { 573 | out(' '); 574 | out(key); 575 | out('="'); 576 | out(encodeEntities(value)); 577 | out('"'); 578 | } 579 | }); 580 | out('>'); 581 | } 582 | }, 583 | end: function(tag) { 584 | tag = lowercase(tag); 585 | if (!ignoreCurrentElement && validElements[tag] === true && voidElements[tag] !== true) { 586 | out(''); 589 | } 590 | // eslint-disable-next-line eqeqeq 591 | if (tag == ignoreCurrentElement) { 592 | ignoreCurrentElement = false; 593 | } 594 | }, 595 | chars: function(chars) { 596 | if (!ignoreCurrentElement) { 597 | out(encodeEntities(chars)); 598 | } 599 | } 600 | }; 601 | } 602 | 603 | 604 | /** 605 | * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1' attribute to declare 606 | * ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo'). This is undesirable since we don't want 607 | * to allow any of these custom attributes. This method strips them all. 608 | * 609 | * @param node Root element to process 610 | */ 611 | function stripCustomNsAttrs(node) { 612 | while (node) { 613 | if (node.nodeType === window.Node.ELEMENT_NODE) { 614 | var attrs = node.attributes; 615 | for (var i = 0, l = attrs.length; i < l; i++) { 616 | var attrNode = attrs[i]; 617 | var attrName = attrNode.name.toLowerCase(); 618 | if (attrName === 'xmlns:ns1' || attrName.lastIndexOf('ns1:', 0) === 0) { 619 | node.removeAttributeNode(attrNode); 620 | i--; 621 | l--; 622 | } 623 | } 624 | } 625 | 626 | var nextNode = node.firstChild; 627 | if (nextNode) { 628 | stripCustomNsAttrs(nextNode); 629 | } 630 | 631 | node = node.nextSibling; 632 | } 633 | } 634 | } 635 | 636 | function sanitizeText(chars) { 637 | var buf = []; 638 | var writer = htmlSanitizeWriter(buf, noop); 639 | writer.chars(chars); 640 | return buf.join(''); 641 | } 642 | 643 | 644 | // define ngSanitize module and register $sanitize service 645 | angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider); 646 | 647 | /** 648 | * @ngdoc filter 649 | * @name linky 650 | * @kind function 651 | * 652 | * @description 653 | * Finds links in text input and turns them into html links. Supports `http/https/ftp/mailto` and 654 | * plain email address links. 655 | * 656 | * Requires the {@link ngSanitize `ngSanitize`} module to be installed. 657 | * 658 | * @param {string} text Input text. 659 | * @param {string} target Window (`_blank|_self|_parent|_top`) or named frame to open links in. 660 | * @param {object|function(url)} [attributes] Add custom attributes to the link element. 661 | * 662 | * Can be one of: 663 | * 664 | * - `object`: A map of attributes 665 | * - `function`: Takes the url as a parameter and returns a map of attributes 666 | * 667 | * If the map of attributes contains a value for `target`, it overrides the value of 668 | * the target parameter. 669 | * 670 | * 671 | * @returns {string} Html-linkified and {@link $sanitize sanitized} text. 672 | * 673 | * @usage 674 | 675 | * 676 | * @example 677 | 678 | 679 |
680 | Snippet: 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 692 | 695 | 696 | 697 | 698 | 701 | 704 | 705 | 706 | 707 | 710 | 713 | 714 | 715 | 716 | 717 | 718 | 719 |
FilterSourceRendered
linky filter 690 |
<div ng-bind-html="snippet | linky">
</div>
691 |
693 |
694 |
linky target 699 |
<div ng-bind-html="snippetWithSingleURL | linky:'_blank'">
</div>
700 |
702 |
703 |
linky custom attributes 708 |
<div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}">
</div>
709 |
711 |
712 |
no filter
<div ng-bind="snippet">
</div>
720 | 721 | 722 | angular.module('linkyExample', ['ngSanitize']) 723 | .controller('ExampleController', ['$scope', function($scope) { 724 | $scope.snippet = 725 | 'Pretty text with some links:\n' + 726 | 'http://angularjs.org/,\n' + 727 | 'mailto:us@somewhere.org,\n' + 728 | 'another@somewhere.org,\n' + 729 | 'and one more: ftp://127.0.0.1/.'; 730 | $scope.snippetWithSingleURL = 'http://angularjs.org/'; 731 | }]); 732 | 733 | 734 | it('should linkify the snippet with urls', function() { 735 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). 736 | toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' + 737 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); 738 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(4); 739 | }); 740 | 741 | it('should not linkify snippet without the linky filter', function() { 742 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()). 743 | toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' + 744 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); 745 | expect(element.all(by.css('#escaped-html a')).count()).toEqual(0); 746 | }); 747 | 748 | it('should update', function() { 749 | element(by.model('snippet')).clear(); 750 | element(by.model('snippet')).sendKeys('new http://link.'); 751 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). 752 | toBe('new http://link.'); 753 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(1); 754 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()) 755 | .toBe('new http://link.'); 756 | }); 757 | 758 | it('should work with the target property', function() { 759 | expect(element(by.id('linky-target')). 760 | element(by.binding("snippetWithSingleURL | linky:'_blank'")).getText()). 761 | toBe('http://angularjs.org/'); 762 | expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank'); 763 | }); 764 | 765 | it('should optionally add custom attributes', function() { 766 | expect(element(by.id('linky-custom-attributes')). 767 | element(by.binding("snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}")).getText()). 768 | toBe('http://angularjs.org/'); 769 | expect(element(by.css('#linky-custom-attributes a')).getAttribute('rel')).toEqual('nofollow'); 770 | }); 771 | 772 | 773 | */ 774 | angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) { 775 | var LINKY_URL_REGEXP = 776 | /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i, 777 | MAILTO_REGEXP = /^mailto:/i; 778 | 779 | var linkyMinErr = angular.$$minErr('linky'); 780 | var isDefined = angular.isDefined; 781 | var isFunction = angular.isFunction; 782 | var isObject = angular.isObject; 783 | var isString = angular.isString; 784 | 785 | return function(text, target, attributes) { 786 | if (text == null || text === '') return text; 787 | if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text); 788 | 789 | var attributesFn = 790 | isFunction(attributes) ? attributes : 791 | isObject(attributes) ? function getAttributesObject() {return attributes;} : 792 | function getEmptyAttributesObject() {return {};}; 793 | 794 | var match; 795 | var raw = text; 796 | var html = []; 797 | var url; 798 | var i; 799 | while ((match = raw.match(LINKY_URL_REGEXP))) { 800 | // We can not end in these as they are sometimes found at the end of the sentence 801 | url = match[0]; 802 | // if we did not match ftp/http/www/mailto then assume mailto 803 | if (!match[2] && !match[4]) { 804 | url = (match[3] ? 'http://' : 'mailto:') + url; 805 | } 806 | i = match.index; 807 | addText(raw.substr(0, i)); 808 | addLink(url, match[0].replace(MAILTO_REGEXP, '')); 809 | raw = raw.substring(i + match[0].length); 810 | } 811 | addText(raw); 812 | return $sanitize(html.join('')); 813 | 814 | function addText(text) { 815 | if (!text) { 816 | return; 817 | } 818 | html.push(sanitizeText(text)); 819 | } 820 | 821 | function addLink(url, text) { 822 | var key, linkAttributes = attributesFn(url); 823 | html.push(''); 837 | addText(text); 838 | html.push(''); 839 | } 840 | }; 841 | }]); 842 | 843 | 844 | })(window, window.angular); 845 | 846 | 847 | /***/ }, 848 | 849 | /***/ 309: 850 | /***/ function(module, exports, __webpack_require__) { 851 | 852 | 'use strict'; 853 | 854 | Object.defineProperty(exports, "__esModule", { 855 | value: true 856 | }); 857 | 858 | var _classCallCheck2 = __webpack_require__(310); 859 | 860 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); 861 | 862 | var _createClass2 = __webpack_require__(311); 863 | 864 | var _createClass3 = _interopRequireDefault(_createClass2); 865 | 866 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 867 | 868 | var HelperController = function () { 869 | function HelperController($scope, SBInterceptor) { 870 | (0, _classCallCheck3.default)(this, HelperController); 871 | 872 | this.$scope = $scope; 873 | 874 | // Allowed events from parrent iFrame 875 | this.events = { 876 | 'component': this.loadComponent, 877 | 'model': this.loadModel 878 | }; 879 | } 880 | 881 | (0, _createClass3.default)(HelperController, [{ 882 | key: '$onInit', 883 | value: function $onInit() { 884 | var _this = this; 885 | 886 | // Tell sb that helper already loaded; 887 | window.parent.sb.contact(); 888 | 889 | // Register lissener for render new component 890 | this.postMessageListener = window.addEventListener('message', function (event) { 891 | event.data && _this.events[event.data.type].call(_this, event.data); 892 | }, false); 893 | } 894 | }, { 895 | key: '$onDestroy', 896 | value: function $onDestroy() { 897 | this.postMessageListener(); 898 | } 899 | }, { 900 | key: 'loadModel', 901 | value: function loadModel(model) { 902 | if (model) { 903 | for (var k in model) { 904 | this[k] = model[k]; 905 | } 906 | } 907 | this.$scope.$apply(); 908 | } 909 | }, { 910 | key: 'loadComponent', 911 | value: function loadComponent(entity) { 912 | var component = window.parent.sb.getStory(entity.data); 913 | this.template = component.template; 914 | if (component.model) { 915 | for (var k in component.model) { 916 | this[k] = component.model[k]; 917 | } 918 | } 919 | this.$scope.$apply(); 920 | } 921 | }]); 922 | return HelperController; 923 | }(); 924 | 925 | exports.default = HelperController; 926 | 927 | /***/ }, 928 | 929 | /***/ 310: 930 | /***/ function(module, exports) { 931 | 932 | "use strict"; 933 | 934 | exports.__esModule = true; 935 | 936 | exports.default = function (instance, Constructor) { 937 | if (!(instance instanceof Constructor)) { 938 | throw new TypeError("Cannot call a class as a function"); 939 | } 940 | }; 941 | 942 | /***/ }, 943 | 944 | /***/ 311: 945 | /***/ function(module, exports, __webpack_require__) { 946 | 947 | "use strict"; 948 | 949 | exports.__esModule = true; 950 | 951 | var _defineProperty = __webpack_require__(312); 952 | 953 | var _defineProperty2 = _interopRequireDefault(_defineProperty); 954 | 955 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 956 | 957 | exports.default = function () { 958 | function defineProperties(target, props) { 959 | for (var i = 0; i < props.length; i++) { 960 | var descriptor = props[i]; 961 | descriptor.enumerable = descriptor.enumerable || false; 962 | descriptor.configurable = true; 963 | if ("value" in descriptor) descriptor.writable = true; 964 | (0, _defineProperty2.default)(target, descriptor.key, descriptor); 965 | } 966 | } 967 | 968 | return function (Constructor, protoProps, staticProps) { 969 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 970 | if (staticProps) defineProperties(Constructor, staticProps); 971 | return Constructor; 972 | }; 973 | }(); 974 | 975 | /***/ }, 976 | 977 | /***/ 312: 978 | /***/ function(module, exports, __webpack_require__) { 979 | 980 | module.exports = { "default": __webpack_require__(313), __esModule: true }; 981 | 982 | /***/ }, 983 | 984 | /***/ 313: 985 | /***/ function(module, exports, __webpack_require__) { 986 | 987 | __webpack_require__(314); 988 | var $Object = __webpack_require__(317).Object; 989 | module.exports = function defineProperty(it, key, desc){ 990 | return $Object.defineProperty(it, key, desc); 991 | }; 992 | 993 | /***/ }, 994 | 995 | /***/ 314: 996 | /***/ function(module, exports, __webpack_require__) { 997 | 998 | var $export = __webpack_require__(315); 999 | // 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes) 1000 | $export($export.S + $export.F * !__webpack_require__(325), 'Object', {defineProperty: __webpack_require__(321).f}); 1001 | 1002 | /***/ }, 1003 | 1004 | /***/ 315: 1005 | /***/ function(module, exports, __webpack_require__) { 1006 | 1007 | var global = __webpack_require__(316) 1008 | , core = __webpack_require__(317) 1009 | , ctx = __webpack_require__(318) 1010 | , hide = __webpack_require__(320) 1011 | , PROTOTYPE = 'prototype'; 1012 | 1013 | var $export = function(type, name, source){ 1014 | var IS_FORCED = type & $export.F 1015 | , IS_GLOBAL = type & $export.G 1016 | , IS_STATIC = type & $export.S 1017 | , IS_PROTO = type & $export.P 1018 | , IS_BIND = type & $export.B 1019 | , IS_WRAP = type & $export.W 1020 | , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) 1021 | , expProto = exports[PROTOTYPE] 1022 | , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] 1023 | , key, own, out; 1024 | if(IS_GLOBAL)source = name; 1025 | for(key in source){ 1026 | // contains in native 1027 | own = !IS_FORCED && target && target[key] !== undefined; 1028 | if(own && key in exports)continue; 1029 | // export native or passed 1030 | out = own ? target[key] : source[key]; 1031 | // prevent global pollution for namespaces 1032 | exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] 1033 | // bind timers to global for call from export context 1034 | : IS_BIND && own ? ctx(out, global) 1035 | // wrap global constructors for prevent change them in library 1036 | : IS_WRAP && target[key] == out ? (function(C){ 1037 | var F = function(a, b, c){ 1038 | if(this instanceof C){ 1039 | switch(arguments.length){ 1040 | case 0: return new C; 1041 | case 1: return new C(a); 1042 | case 2: return new C(a, b); 1043 | } return new C(a, b, c); 1044 | } return C.apply(this, arguments); 1045 | }; 1046 | F[PROTOTYPE] = C[PROTOTYPE]; 1047 | return F; 1048 | // make static versions for prototype methods 1049 | })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; 1050 | // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% 1051 | if(IS_PROTO){ 1052 | (exports.virtual || (exports.virtual = {}))[key] = out; 1053 | // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% 1054 | if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out); 1055 | } 1056 | } 1057 | }; 1058 | // type bitmap 1059 | $export.F = 1; // forced 1060 | $export.G = 2; // global 1061 | $export.S = 4; // static 1062 | $export.P = 8; // proto 1063 | $export.B = 16; // bind 1064 | $export.W = 32; // wrap 1065 | $export.U = 64; // safe 1066 | $export.R = 128; // real proto method for `library` 1067 | module.exports = $export; 1068 | 1069 | /***/ }, 1070 | 1071 | /***/ 316: 1072 | /***/ function(module, exports) { 1073 | 1074 | // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 1075 | var global = module.exports = typeof window != 'undefined' && window.Math == Math 1076 | ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); 1077 | if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef 1078 | 1079 | /***/ }, 1080 | 1081 | /***/ 317: 1082 | /***/ function(module, exports) { 1083 | 1084 | var core = module.exports = {version: '2.4.0'}; 1085 | if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef 1086 | 1087 | /***/ }, 1088 | 1089 | /***/ 318: 1090 | /***/ function(module, exports, __webpack_require__) { 1091 | 1092 | // optional / simple context binding 1093 | var aFunction = __webpack_require__(319); 1094 | module.exports = function(fn, that, length){ 1095 | aFunction(fn); 1096 | if(that === undefined)return fn; 1097 | switch(length){ 1098 | case 1: return function(a){ 1099 | return fn.call(that, a); 1100 | }; 1101 | case 2: return function(a, b){ 1102 | return fn.call(that, a, b); 1103 | }; 1104 | case 3: return function(a, b, c){ 1105 | return fn.call(that, a, b, c); 1106 | }; 1107 | } 1108 | return function(/* ...args */){ 1109 | return fn.apply(that, arguments); 1110 | }; 1111 | }; 1112 | 1113 | /***/ }, 1114 | 1115 | /***/ 319: 1116 | /***/ function(module, exports) { 1117 | 1118 | module.exports = function(it){ 1119 | if(typeof it != 'function')throw TypeError(it + ' is not a function!'); 1120 | return it; 1121 | }; 1122 | 1123 | /***/ }, 1124 | 1125 | /***/ 320: 1126 | /***/ function(module, exports, __webpack_require__) { 1127 | 1128 | var dP = __webpack_require__(321) 1129 | , createDesc = __webpack_require__(329); 1130 | module.exports = __webpack_require__(325) ? function(object, key, value){ 1131 | return dP.f(object, key, createDesc(1, value)); 1132 | } : function(object, key, value){ 1133 | object[key] = value; 1134 | return object; 1135 | }; 1136 | 1137 | /***/ }, 1138 | 1139 | /***/ 321: 1140 | /***/ function(module, exports, __webpack_require__) { 1141 | 1142 | var anObject = __webpack_require__(322) 1143 | , IE8_DOM_DEFINE = __webpack_require__(324) 1144 | , toPrimitive = __webpack_require__(328) 1145 | , dP = Object.defineProperty; 1146 | 1147 | exports.f = __webpack_require__(325) ? Object.defineProperty : function defineProperty(O, P, Attributes){ 1148 | anObject(O); 1149 | P = toPrimitive(P, true); 1150 | anObject(Attributes); 1151 | if(IE8_DOM_DEFINE)try { 1152 | return dP(O, P, Attributes); 1153 | } catch(e){ /* empty */ } 1154 | if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!'); 1155 | if('value' in Attributes)O[P] = Attributes.value; 1156 | return O; 1157 | }; 1158 | 1159 | /***/ }, 1160 | 1161 | /***/ 322: 1162 | /***/ function(module, exports, __webpack_require__) { 1163 | 1164 | var isObject = __webpack_require__(323); 1165 | module.exports = function(it){ 1166 | if(!isObject(it))throw TypeError(it + ' is not an object!'); 1167 | return it; 1168 | }; 1169 | 1170 | /***/ }, 1171 | 1172 | /***/ 323: 1173 | /***/ function(module, exports) { 1174 | 1175 | module.exports = function(it){ 1176 | return typeof it === 'object' ? it !== null : typeof it === 'function'; 1177 | }; 1178 | 1179 | /***/ }, 1180 | 1181 | /***/ 324: 1182 | /***/ function(module, exports, __webpack_require__) { 1183 | 1184 | module.exports = !__webpack_require__(325) && !__webpack_require__(326)(function(){ 1185 | return Object.defineProperty(__webpack_require__(327)('div'), 'a', {get: function(){ return 7; }}).a != 7; 1186 | }); 1187 | 1188 | /***/ }, 1189 | 1190 | /***/ 325: 1191 | /***/ function(module, exports, __webpack_require__) { 1192 | 1193 | // Thank's IE8 for his funny defineProperty 1194 | module.exports = !__webpack_require__(326)(function(){ 1195 | return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; 1196 | }); 1197 | 1198 | /***/ }, 1199 | 1200 | /***/ 326: 1201 | /***/ function(module, exports) { 1202 | 1203 | module.exports = function(exec){ 1204 | try { 1205 | return !!exec(); 1206 | } catch(e){ 1207 | return true; 1208 | } 1209 | }; 1210 | 1211 | /***/ }, 1212 | 1213 | /***/ 327: 1214 | /***/ function(module, exports, __webpack_require__) { 1215 | 1216 | var isObject = __webpack_require__(323) 1217 | , document = __webpack_require__(316).document 1218 | // in old IE typeof document.createElement is 'object' 1219 | , is = isObject(document) && isObject(document.createElement); 1220 | module.exports = function(it){ 1221 | return is ? document.createElement(it) : {}; 1222 | }; 1223 | 1224 | /***/ }, 1225 | 1226 | /***/ 328: 1227 | /***/ function(module, exports, __webpack_require__) { 1228 | 1229 | // 7.1.1 ToPrimitive(input [, PreferredType]) 1230 | var isObject = __webpack_require__(323); 1231 | // instead of the ES6 spec version, we didn't implement @@toPrimitive case 1232 | // and the second argument - flag - preferred type is a string 1233 | module.exports = function(it, S){ 1234 | if(!isObject(it))return it; 1235 | var fn, val; 1236 | if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; 1237 | if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val; 1238 | if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; 1239 | throw TypeError("Can't convert object to primitive value"); 1240 | }; 1241 | 1242 | /***/ }, 1243 | 1244 | /***/ 329: 1245 | /***/ function(module, exports) { 1246 | 1247 | module.exports = function(bitmap, value){ 1248 | return { 1249 | enumerable : !(bitmap & 1), 1250 | configurable: !(bitmap & 2), 1251 | writable : !(bitmap & 4), 1252 | value : value 1253 | }; 1254 | }; 1255 | 1256 | /***/ }, 1257 | 1258 | /***/ 330: 1259 | /***/ function(module, exports) { 1260 | 1261 | "use strict"; 1262 | 1263 | Object.defineProperty(exports, "__esModule", { 1264 | value: true 1265 | }); 1266 | 1267 | exports.default = function ($compile) { 1268 | return function (scope, element, attrs) { 1269 | scope.$watch(function (scope) { 1270 | return scope.$eval(attrs.compile); 1271 | }, function (value) { 1272 | element.html(value); 1273 | $compile(element.contents())(scope); 1274 | }); 1275 | }; 1276 | }; 1277 | 1278 | /***/ }, 1279 | 1280 | /***/ 331: 1281 | /***/ function(module, exports, __webpack_require__) { 1282 | 1283 | 'use strict'; 1284 | 1285 | Object.defineProperty(exports, "__esModule", { 1286 | value: true 1287 | }); 1288 | 1289 | var _classCallCheck2 = __webpack_require__(310); 1290 | 1291 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); 1292 | 1293 | var _createClass2 = __webpack_require__(311); 1294 | 1295 | var _createClass3 = _interopRequireDefault(_createClass2); 1296 | 1297 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1298 | 1299 | var InterceptorController = function () { 1300 | function InterceptorController() { 1301 | (0, _classCallCheck3.default)(this, InterceptorController); 1302 | 1303 | this.requests = {}; 1304 | this.updateXHROpenMethod(); 1305 | } 1306 | 1307 | (0, _createClass3.default)(InterceptorController, [{ 1308 | key: 'updateXHROpenMethod', 1309 | value: function updateXHROpenMethod() { 1310 | var self = this; 1311 | this.origOpen = XMLHttpRequest.prototype.open; 1312 | XMLHttpRequest.prototype.open = function (type, url) { 1313 | var _this = this; 1314 | 1315 | // Skip request to browser-sync 1316 | if (url.indexOf('browser-sync/socket.io') === -1) { 1317 | (function () { 1318 | var id = self.generateID(); 1319 | var inProgress = true; 1320 | var request = { type: type, url: url, inProgress: inProgress, id: id }; 1321 | 1322 | self.sendRequestToSB(request); 1323 | 1324 | _this.addEventListener('load', function () { 1325 | try { 1326 | request.responce = JSON.parse(this.responseText); 1327 | } catch (e) {} 1328 | request.status = this.status; 1329 | request.statusText = this.statusText; 1330 | request.inProgress = false; 1331 | self.sendRequestToSB(request, 'update'); 1332 | }); 1333 | })(); 1334 | } 1335 | 1336 | self.origOpen.apply(this, arguments); 1337 | }; 1338 | } 1339 | }, { 1340 | key: 'sendRequestToSB', 1341 | value: function sendRequestToSB(request) { 1342 | var message = 'xhr'; 1343 | window.parent.postMessage({ message: message, request: request }, '*'); 1344 | } 1345 | }, { 1346 | key: 'generateID', 1347 | value: function generateID() { 1348 | return Math.random().toString(36).substr(2, 10); 1349 | } 1350 | }]); 1351 | return InterceptorController; 1352 | }(); 1353 | 1354 | exports.default = InterceptorController; 1355 | 1356 | /***/ } 1357 | 1358 | /******/ }); -------------------------------------------------------------------------------- /dist/stories.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) 10 | /******/ return installedModules[moduleId].exports; 11 | 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ exports: {}, 15 | /******/ id: moduleId, 16 | /******/ loaded: false 17 | /******/ }; 18 | 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | 22 | /******/ // Flag the module as loaded 23 | /******/ module.loaded = true; 24 | 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | 29 | 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | 36 | /******/ // __webpack_public_path__ 37 | /******/ __webpack_require__.p = ""; 38 | 39 | /******/ // Load entry module and return exports 40 | /******/ return __webpack_require__(0); 41 | /******/ }) 42 | /************************************************************************/ 43 | /******/ ({ 44 | 45 | /***/ 0: 46 | /***/ function(module, exports, __webpack_require__) { 47 | 48 | module.exports = __webpack_require__(428); 49 | 50 | 51 | /***/ }, 52 | 53 | /***/ 310: 54 | /***/ function(module, exports) { 55 | 56 | "use strict"; 57 | 58 | exports.__esModule = true; 59 | 60 | exports.default = function (instance, Constructor) { 61 | if (!(instance instanceof Constructor)) { 62 | throw new TypeError("Cannot call a class as a function"); 63 | } 64 | }; 65 | 66 | /***/ }, 67 | 68 | /***/ 311: 69 | /***/ function(module, exports, __webpack_require__) { 70 | 71 | "use strict"; 72 | 73 | exports.__esModule = true; 74 | 75 | var _defineProperty = __webpack_require__(312); 76 | 77 | var _defineProperty2 = _interopRequireDefault(_defineProperty); 78 | 79 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 80 | 81 | exports.default = function () { 82 | function defineProperties(target, props) { 83 | for (var i = 0; i < props.length; i++) { 84 | var descriptor = props[i]; 85 | descriptor.enumerable = descriptor.enumerable || false; 86 | descriptor.configurable = true; 87 | if ("value" in descriptor) descriptor.writable = true; 88 | (0, _defineProperty2.default)(target, descriptor.key, descriptor); 89 | } 90 | } 91 | 92 | return function (Constructor, protoProps, staticProps) { 93 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 94 | if (staticProps) defineProperties(Constructor, staticProps); 95 | return Constructor; 96 | }; 97 | }(); 98 | 99 | /***/ }, 100 | 101 | /***/ 312: 102 | /***/ function(module, exports, __webpack_require__) { 103 | 104 | module.exports = { "default": __webpack_require__(313), __esModule: true }; 105 | 106 | /***/ }, 107 | 108 | /***/ 313: 109 | /***/ function(module, exports, __webpack_require__) { 110 | 111 | __webpack_require__(314); 112 | var $Object = __webpack_require__(317).Object; 113 | module.exports = function defineProperty(it, key, desc){ 114 | return $Object.defineProperty(it, key, desc); 115 | }; 116 | 117 | /***/ }, 118 | 119 | /***/ 314: 120 | /***/ function(module, exports, __webpack_require__) { 121 | 122 | var $export = __webpack_require__(315); 123 | // 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes) 124 | $export($export.S + $export.F * !__webpack_require__(325), 'Object', {defineProperty: __webpack_require__(321).f}); 125 | 126 | /***/ }, 127 | 128 | /***/ 315: 129 | /***/ function(module, exports, __webpack_require__) { 130 | 131 | var global = __webpack_require__(316) 132 | , core = __webpack_require__(317) 133 | , ctx = __webpack_require__(318) 134 | , hide = __webpack_require__(320) 135 | , PROTOTYPE = 'prototype'; 136 | 137 | var $export = function(type, name, source){ 138 | var IS_FORCED = type & $export.F 139 | , IS_GLOBAL = type & $export.G 140 | , IS_STATIC = type & $export.S 141 | , IS_PROTO = type & $export.P 142 | , IS_BIND = type & $export.B 143 | , IS_WRAP = type & $export.W 144 | , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) 145 | , expProto = exports[PROTOTYPE] 146 | , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] 147 | , key, own, out; 148 | if(IS_GLOBAL)source = name; 149 | for(key in source){ 150 | // contains in native 151 | own = !IS_FORCED && target && target[key] !== undefined; 152 | if(own && key in exports)continue; 153 | // export native or passed 154 | out = own ? target[key] : source[key]; 155 | // prevent global pollution for namespaces 156 | exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] 157 | // bind timers to global for call from export context 158 | : IS_BIND && own ? ctx(out, global) 159 | // wrap global constructors for prevent change them in library 160 | : IS_WRAP && target[key] == out ? (function(C){ 161 | var F = function(a, b, c){ 162 | if(this instanceof C){ 163 | switch(arguments.length){ 164 | case 0: return new C; 165 | case 1: return new C(a); 166 | case 2: return new C(a, b); 167 | } return new C(a, b, c); 168 | } return C.apply(this, arguments); 169 | }; 170 | F[PROTOTYPE] = C[PROTOTYPE]; 171 | return F; 172 | // make static versions for prototype methods 173 | })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; 174 | // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% 175 | if(IS_PROTO){ 176 | (exports.virtual || (exports.virtual = {}))[key] = out; 177 | // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% 178 | if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out); 179 | } 180 | } 181 | }; 182 | // type bitmap 183 | $export.F = 1; // forced 184 | $export.G = 2; // global 185 | $export.S = 4; // static 186 | $export.P = 8; // proto 187 | $export.B = 16; // bind 188 | $export.W = 32; // wrap 189 | $export.U = 64; // safe 190 | $export.R = 128; // real proto method for `library` 191 | module.exports = $export; 192 | 193 | /***/ }, 194 | 195 | /***/ 316: 196 | /***/ function(module, exports) { 197 | 198 | // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 199 | var global = module.exports = typeof window != 'undefined' && window.Math == Math 200 | ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); 201 | if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef 202 | 203 | /***/ }, 204 | 205 | /***/ 317: 206 | /***/ function(module, exports) { 207 | 208 | var core = module.exports = {version: '2.4.0'}; 209 | if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef 210 | 211 | /***/ }, 212 | 213 | /***/ 318: 214 | /***/ function(module, exports, __webpack_require__) { 215 | 216 | // optional / simple context binding 217 | var aFunction = __webpack_require__(319); 218 | module.exports = function(fn, that, length){ 219 | aFunction(fn); 220 | if(that === undefined)return fn; 221 | switch(length){ 222 | case 1: return function(a){ 223 | return fn.call(that, a); 224 | }; 225 | case 2: return function(a, b){ 226 | return fn.call(that, a, b); 227 | }; 228 | case 3: return function(a, b, c){ 229 | return fn.call(that, a, b, c); 230 | }; 231 | } 232 | return function(/* ...args */){ 233 | return fn.apply(that, arguments); 234 | }; 235 | }; 236 | 237 | /***/ }, 238 | 239 | /***/ 319: 240 | /***/ function(module, exports) { 241 | 242 | module.exports = function(it){ 243 | if(typeof it != 'function')throw TypeError(it + ' is not a function!'); 244 | return it; 245 | }; 246 | 247 | /***/ }, 248 | 249 | /***/ 320: 250 | /***/ function(module, exports, __webpack_require__) { 251 | 252 | var dP = __webpack_require__(321) 253 | , createDesc = __webpack_require__(329); 254 | module.exports = __webpack_require__(325) ? function(object, key, value){ 255 | return dP.f(object, key, createDesc(1, value)); 256 | } : function(object, key, value){ 257 | object[key] = value; 258 | return object; 259 | }; 260 | 261 | /***/ }, 262 | 263 | /***/ 321: 264 | /***/ function(module, exports, __webpack_require__) { 265 | 266 | var anObject = __webpack_require__(322) 267 | , IE8_DOM_DEFINE = __webpack_require__(324) 268 | , toPrimitive = __webpack_require__(328) 269 | , dP = Object.defineProperty; 270 | 271 | exports.f = __webpack_require__(325) ? Object.defineProperty : function defineProperty(O, P, Attributes){ 272 | anObject(O); 273 | P = toPrimitive(P, true); 274 | anObject(Attributes); 275 | if(IE8_DOM_DEFINE)try { 276 | return dP(O, P, Attributes); 277 | } catch(e){ /* empty */ } 278 | if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!'); 279 | if('value' in Attributes)O[P] = Attributes.value; 280 | return O; 281 | }; 282 | 283 | /***/ }, 284 | 285 | /***/ 322: 286 | /***/ function(module, exports, __webpack_require__) { 287 | 288 | var isObject = __webpack_require__(323); 289 | module.exports = function(it){ 290 | if(!isObject(it))throw TypeError(it + ' is not an object!'); 291 | return it; 292 | }; 293 | 294 | /***/ }, 295 | 296 | /***/ 323: 297 | /***/ function(module, exports) { 298 | 299 | module.exports = function(it){ 300 | return typeof it === 'object' ? it !== null : typeof it === 'function'; 301 | }; 302 | 303 | /***/ }, 304 | 305 | /***/ 324: 306 | /***/ function(module, exports, __webpack_require__) { 307 | 308 | module.exports = !__webpack_require__(325) && !__webpack_require__(326)(function(){ 309 | return Object.defineProperty(__webpack_require__(327)('div'), 'a', {get: function(){ return 7; }}).a != 7; 310 | }); 311 | 312 | /***/ }, 313 | 314 | /***/ 325: 315 | /***/ function(module, exports, __webpack_require__) { 316 | 317 | // Thank's IE8 for his funny defineProperty 318 | module.exports = !__webpack_require__(326)(function(){ 319 | return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; 320 | }); 321 | 322 | /***/ }, 323 | 324 | /***/ 326: 325 | /***/ function(module, exports) { 326 | 327 | module.exports = function(exec){ 328 | try { 329 | return !!exec(); 330 | } catch(e){ 331 | return true; 332 | } 333 | }; 334 | 335 | /***/ }, 336 | 337 | /***/ 327: 338 | /***/ function(module, exports, __webpack_require__) { 339 | 340 | var isObject = __webpack_require__(323) 341 | , document = __webpack_require__(316).document 342 | // in old IE typeof document.createElement is 'object' 343 | , is = isObject(document) && isObject(document.createElement); 344 | module.exports = function(it){ 345 | return is ? document.createElement(it) : {}; 346 | }; 347 | 348 | /***/ }, 349 | 350 | /***/ 328: 351 | /***/ function(module, exports, __webpack_require__) { 352 | 353 | // 7.1.1 ToPrimitive(input [, PreferredType]) 354 | var isObject = __webpack_require__(323); 355 | // instead of the ES6 spec version, we didn't implement @@toPrimitive case 356 | // and the second argument - flag - preferred type is a string 357 | module.exports = function(it, S){ 358 | if(!isObject(it))return it; 359 | var fn, val; 360 | if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; 361 | if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val; 362 | if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; 363 | throw TypeError("Can't convert object to primitive value"); 364 | }; 365 | 366 | /***/ }, 367 | 368 | /***/ 329: 369 | /***/ function(module, exports) { 370 | 371 | module.exports = function(bitmap, value){ 372 | return { 373 | enumerable : !(bitmap & 1), 374 | configurable: !(bitmap & 2), 375 | writable : !(bitmap & 4), 376 | value : value 377 | }; 378 | }; 379 | 380 | /***/ }, 381 | 382 | /***/ 367: 383 | /***/ function(module, exports, __webpack_require__) { 384 | 385 | // 7.1.13 ToObject(argument) 386 | var defined = __webpack_require__(368); 387 | module.exports = function(it){ 388 | return Object(defined(it)); 389 | }; 390 | 391 | /***/ }, 392 | 393 | /***/ 368: 394 | /***/ function(module, exports) { 395 | 396 | // 7.2.1 RequireObjectCoercible(argument) 397 | module.exports = function(it){ 398 | if(it == undefined)throw TypeError("Can't call method on " + it); 399 | return it; 400 | }; 401 | 402 | /***/ }, 403 | 404 | /***/ 369: 405 | /***/ function(module, exports, __webpack_require__) { 406 | 407 | // 19.1.2.14 / 15.2.3.14 Object.keys(O) 408 | var $keys = __webpack_require__(370) 409 | , enumBugKeys = __webpack_require__(382); 410 | 411 | module.exports = Object.keys || function keys(O){ 412 | return $keys(O, enumBugKeys); 413 | }; 414 | 415 | /***/ }, 416 | 417 | /***/ 370: 418 | /***/ function(module, exports, __webpack_require__) { 419 | 420 | var has = __webpack_require__(371) 421 | , toIObject = __webpack_require__(372) 422 | , arrayIndexOf = __webpack_require__(375)(false) 423 | , IE_PROTO = __webpack_require__(379)('IE_PROTO'); 424 | 425 | module.exports = function(object, names){ 426 | var O = toIObject(object) 427 | , i = 0 428 | , result = [] 429 | , key; 430 | for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key); 431 | // Don't enum bug & hidden keys 432 | while(names.length > i)if(has(O, key = names[i++])){ 433 | ~arrayIndexOf(result, key) || result.push(key); 434 | } 435 | return result; 436 | }; 437 | 438 | /***/ }, 439 | 440 | /***/ 371: 441 | /***/ function(module, exports) { 442 | 443 | var hasOwnProperty = {}.hasOwnProperty; 444 | module.exports = function(it, key){ 445 | return hasOwnProperty.call(it, key); 446 | }; 447 | 448 | /***/ }, 449 | 450 | /***/ 372: 451 | /***/ function(module, exports, __webpack_require__) { 452 | 453 | // to indexed object, toObject with fallback for non-array-like ES3 strings 454 | var IObject = __webpack_require__(373) 455 | , defined = __webpack_require__(368); 456 | module.exports = function(it){ 457 | return IObject(defined(it)); 458 | }; 459 | 460 | /***/ }, 461 | 462 | /***/ 373: 463 | /***/ function(module, exports, __webpack_require__) { 464 | 465 | // fallback for non-array-like ES3 and non-enumerable old V8 strings 466 | var cof = __webpack_require__(374); 467 | module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){ 468 | return cof(it) == 'String' ? it.split('') : Object(it); 469 | }; 470 | 471 | /***/ }, 472 | 473 | /***/ 374: 474 | /***/ function(module, exports) { 475 | 476 | var toString = {}.toString; 477 | 478 | module.exports = function(it){ 479 | return toString.call(it).slice(8, -1); 480 | }; 481 | 482 | /***/ }, 483 | 484 | /***/ 375: 485 | /***/ function(module, exports, __webpack_require__) { 486 | 487 | // false -> Array#indexOf 488 | // true -> Array#includes 489 | var toIObject = __webpack_require__(372) 490 | , toLength = __webpack_require__(376) 491 | , toIndex = __webpack_require__(378); 492 | module.exports = function(IS_INCLUDES){ 493 | return function($this, el, fromIndex){ 494 | var O = toIObject($this) 495 | , length = toLength(O.length) 496 | , index = toIndex(fromIndex, length) 497 | , value; 498 | // Array#includes uses SameValueZero equality algorithm 499 | if(IS_INCLUDES && el != el)while(length > index){ 500 | value = O[index++]; 501 | if(value != value)return true; 502 | // Array#toIndex ignores holes, Array#includes - not 503 | } else for(;length > index; index++)if(IS_INCLUDES || index in O){ 504 | if(O[index] === el)return IS_INCLUDES || index || 0; 505 | } return !IS_INCLUDES && -1; 506 | }; 507 | }; 508 | 509 | /***/ }, 510 | 511 | /***/ 376: 512 | /***/ function(module, exports, __webpack_require__) { 513 | 514 | // 7.1.15 ToLength 515 | var toInteger = __webpack_require__(377) 516 | , min = Math.min; 517 | module.exports = function(it){ 518 | return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 519 | }; 520 | 521 | /***/ }, 522 | 523 | /***/ 377: 524 | /***/ function(module, exports) { 525 | 526 | // 7.1.4 ToInteger 527 | var ceil = Math.ceil 528 | , floor = Math.floor; 529 | module.exports = function(it){ 530 | return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); 531 | }; 532 | 533 | /***/ }, 534 | 535 | /***/ 378: 536 | /***/ function(module, exports, __webpack_require__) { 537 | 538 | var toInteger = __webpack_require__(377) 539 | , max = Math.max 540 | , min = Math.min; 541 | module.exports = function(index, length){ 542 | index = toInteger(index); 543 | return index < 0 ? max(index + length, 0) : min(index, length); 544 | }; 545 | 546 | /***/ }, 547 | 548 | /***/ 379: 549 | /***/ function(module, exports, __webpack_require__) { 550 | 551 | var shared = __webpack_require__(380)('keys') 552 | , uid = __webpack_require__(381); 553 | module.exports = function(key){ 554 | return shared[key] || (shared[key] = uid(key)); 555 | }; 556 | 557 | /***/ }, 558 | 559 | /***/ 380: 560 | /***/ function(module, exports, __webpack_require__) { 561 | 562 | var global = __webpack_require__(316) 563 | , SHARED = '__core-js_shared__' 564 | , store = global[SHARED] || (global[SHARED] = {}); 565 | module.exports = function(key){ 566 | return store[key] || (store[key] = {}); 567 | }; 568 | 569 | /***/ }, 570 | 571 | /***/ 381: 572 | /***/ function(module, exports) { 573 | 574 | var id = 0 575 | , px = Math.random(); 576 | module.exports = function(key){ 577 | return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); 578 | }; 579 | 580 | /***/ }, 581 | 582 | /***/ 382: 583 | /***/ function(module, exports) { 584 | 585 | // IE 8- don't enum bug keys 586 | module.exports = ( 587 | 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' 588 | ).split(','); 589 | 590 | /***/ }, 591 | 592 | /***/ 423: 593 | /***/ function(module, exports) { 594 | 595 | exports.f = Object.getOwnPropertySymbols; 596 | 597 | /***/ }, 598 | 599 | /***/ 424: 600 | /***/ function(module, exports) { 601 | 602 | exports.f = {}.propertyIsEnumerable; 603 | 604 | /***/ }, 605 | 606 | /***/ 428: 607 | /***/ function(module, exports, __webpack_require__) { 608 | 609 | 'use strict'; 610 | 611 | var _typeof2 = __webpack_require__(429); 612 | 613 | var _typeof3 = _interopRequireDefault(_typeof2); 614 | 615 | var _classCallCheck2 = __webpack_require__(310); 616 | 617 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); 618 | 619 | var _createClass2 = __webpack_require__(311); 620 | 621 | var _createClass3 = _interopRequireDefault(_createClass2); 622 | 623 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 624 | 625 | var StoriesAPI = function () { 626 | function StoriesAPI() { 627 | (0, _classCallCheck3.default)(this, StoriesAPI); 628 | 629 | this.sections = {}; 630 | this.mocks = {}; 631 | } 632 | 633 | /** 634 | * Creta new section 635 | * and return API instance that allow create stories 636 | * 637 | * @param name Section name 638 | * @returns function SB API instance 639 | */ 640 | 641 | 642 | (0, _createClass3.default)(StoriesAPI, [{ 643 | key: 'section', 644 | value: function section(name) { 645 | var _this = this; 646 | 647 | if (!this.sections[name]) { 648 | this.sections[name] = {}; 649 | } 650 | 651 | var sectionAPI = {}; 652 | 653 | sectionAPI.story = function (storyName) { 654 | var section = _this.sections[name]; 655 | var storyAPI = {}; 656 | storyAPI.add = function (title, template, model, docs) { 657 | if (!section[storyName]) { 658 | section[storyName] = []; 659 | } 660 | var id = Math.random().toString(36).substr(2, 9); 661 | section[storyName].push({ title: title, template: template, model: model, docs: docs, id: id }); 662 | return storyAPI; 663 | }; 664 | return storyAPI; 665 | }; 666 | 667 | return sectionAPI; 668 | } 669 | 670 | /** 671 | * Get all savad sections 672 | * 673 | * @returns object Sections 674 | */ 675 | 676 | }, { 677 | key: 'getSections', 678 | value: function getSections() { 679 | return this.sections; 680 | } 681 | 682 | /** 683 | * Get story from store 684 | * 685 | * @param sbObject Should contaie section, story name and point ID. 686 | * @returns object Story 687 | */ 688 | 689 | }, { 690 | key: 'getStory', 691 | value: function getStory(sbObject) { 692 | try { 693 | // Find story from store 694 | var story = this.sections[sbObject.section][sbObject.story].find(function (i) { 695 | return i.id === sbObject.id; 696 | }); 697 | 698 | // Check if need load mock for story 699 | if (story && typeof story.model === 'string') { 700 | story.model = this.getMock(story.model); 701 | } 702 | return story; 703 | } catch (e) { 704 | console.log(e); 705 | } 706 | } 707 | 708 | /** 709 | * Update story with new data 710 | * Used for save tempalate and model 711 | * Use this method if you need to edit any story param 712 | * 713 | * @param sbObject Should contaie section, story name and point ID. 714 | * @param data Story point that need update 715 | */ 716 | 717 | }, { 718 | key: 'updateStory', 719 | value: function updateStory(sbObject, data) { 720 | var storyPoint = this.getStory(sbObject); 721 | storyPoint = data; 722 | } 723 | 724 | /** 725 | * Store mock for stories. 726 | * Mock can be stored as object. 727 | * 728 | * @param key Mock name 729 | * @param value Mock value. 730 | * @param perform Function witch will call with mocked data 731 | * Use it to perform data structure as you need 732 | */ 733 | 734 | }, { 735 | key: 'mock', 736 | value: function mock(key, value, perform) { 737 | if ((typeof value === 'undefined' ? 'undefined' : (0, _typeof3.default)(value)) === 'object') { 738 | this.mocks[key] = perform ? perform(value) : value; 739 | } else { 740 | throw new Error('Cant\'t save mock for ' + key + '. Mock value should be an object. Double check it.'); 741 | } 742 | } 743 | 744 | /** 745 | * Get mock from store 746 | * 747 | * @param key Mock name 748 | * @returns object Mock 749 | */ 750 | 751 | }, { 752 | key: 'getMock', 753 | value: function getMock(key) { 754 | if (this.mocks[key]) { 755 | return this.mocks[key]; 756 | } else { 757 | throw new Error('Can\'t find mock for ' + key); 758 | } 759 | } 760 | }, { 761 | key: 'registerContactCB', 762 | value: function registerContactCB(cb) { 763 | this.contactCB = cb; 764 | } 765 | }, { 766 | key: 'registerReloadCB', 767 | value: function registerReloadCB(cb) { 768 | this.reloadCB = cb; 769 | } 770 | }, { 771 | key: 'contact', 772 | value: function contact() { 773 | this.contactCB(); 774 | } 775 | }, { 776 | key: 'reload', 777 | value: function reload() { 778 | var _this2 = this; 779 | 780 | if (this.reloadCB) { 781 | this.sections = {}; 782 | setTimeout(function () { 783 | return _this2.reloadCB(); 784 | }, 0); 785 | } 786 | } 787 | }]); 788 | return StoriesAPI; 789 | }(); 790 | 791 | window.sb = new StoriesAPI(); 792 | 793 | /***/ }, 794 | 795 | /***/ 429: 796 | /***/ function(module, exports, __webpack_require__) { 797 | 798 | "use strict"; 799 | 800 | exports.__esModule = true; 801 | 802 | var _iterator = __webpack_require__(430); 803 | 804 | var _iterator2 = _interopRequireDefault(_iterator); 805 | 806 | var _symbol = __webpack_require__(450); 807 | 808 | var _symbol2 = _interopRequireDefault(_symbol); 809 | 810 | var _typeof = typeof _symbol2.default === "function" && typeof _iterator2.default === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof _symbol2.default === "function" && obj.constructor === _symbol2.default ? "symbol" : typeof obj; }; 811 | 812 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 813 | 814 | exports.default = typeof _symbol2.default === "function" && _typeof(_iterator2.default) === "symbol" ? function (obj) { 815 | return typeof obj === "undefined" ? "undefined" : _typeof(obj); 816 | } : function (obj) { 817 | return obj && typeof _symbol2.default === "function" && obj.constructor === _symbol2.default ? "symbol" : typeof obj === "undefined" ? "undefined" : _typeof(obj); 818 | }; 819 | 820 | /***/ }, 821 | 822 | /***/ 430: 823 | /***/ function(module, exports, __webpack_require__) { 824 | 825 | module.exports = { "default": __webpack_require__(431), __esModule: true }; 826 | 827 | /***/ }, 828 | 829 | /***/ 431: 830 | /***/ function(module, exports, __webpack_require__) { 831 | 832 | __webpack_require__(432); 833 | __webpack_require__(445); 834 | module.exports = __webpack_require__(449).f('iterator'); 835 | 836 | /***/ }, 837 | 838 | /***/ 432: 839 | /***/ function(module, exports, __webpack_require__) { 840 | 841 | 'use strict'; 842 | var $at = __webpack_require__(433)(true); 843 | 844 | // 21.1.3.27 String.prototype[@@iterator]() 845 | __webpack_require__(434)(String, 'String', function(iterated){ 846 | this._t = String(iterated); // target 847 | this._i = 0; // next index 848 | // 21.1.5.2.1 %StringIteratorPrototype%.next() 849 | }, function(){ 850 | var O = this._t 851 | , index = this._i 852 | , point; 853 | if(index >= O.length)return {value: undefined, done: true}; 854 | point = $at(O, index); 855 | this._i += point.length; 856 | return {value: point, done: false}; 857 | }); 858 | 859 | /***/ }, 860 | 861 | /***/ 433: 862 | /***/ function(module, exports, __webpack_require__) { 863 | 864 | var toInteger = __webpack_require__(377) 865 | , defined = __webpack_require__(368); 866 | // true -> String#at 867 | // false -> String#codePointAt 868 | module.exports = function(TO_STRING){ 869 | return function(that, pos){ 870 | var s = String(defined(that)) 871 | , i = toInteger(pos) 872 | , l = s.length 873 | , a, b; 874 | if(i < 0 || i >= l)return TO_STRING ? '' : undefined; 875 | a = s.charCodeAt(i); 876 | return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff 877 | ? TO_STRING ? s.charAt(i) : a 878 | : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; 879 | }; 880 | }; 881 | 882 | /***/ }, 883 | 884 | /***/ 434: 885 | /***/ function(module, exports, __webpack_require__) { 886 | 887 | 'use strict'; 888 | var LIBRARY = __webpack_require__(435) 889 | , $export = __webpack_require__(315) 890 | , redefine = __webpack_require__(436) 891 | , hide = __webpack_require__(320) 892 | , has = __webpack_require__(371) 893 | , Iterators = __webpack_require__(437) 894 | , $iterCreate = __webpack_require__(438) 895 | , setToStringTag = __webpack_require__(442) 896 | , getPrototypeOf = __webpack_require__(444) 897 | , ITERATOR = __webpack_require__(443)('iterator') 898 | , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next` 899 | , FF_ITERATOR = '@@iterator' 900 | , KEYS = 'keys' 901 | , VALUES = 'values'; 902 | 903 | var returnThis = function(){ return this; }; 904 | 905 | module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){ 906 | $iterCreate(Constructor, NAME, next); 907 | var getMethod = function(kind){ 908 | if(!BUGGY && kind in proto)return proto[kind]; 909 | switch(kind){ 910 | case KEYS: return function keys(){ return new Constructor(this, kind); }; 911 | case VALUES: return function values(){ return new Constructor(this, kind); }; 912 | } return function entries(){ return new Constructor(this, kind); }; 913 | }; 914 | var TAG = NAME + ' Iterator' 915 | , DEF_VALUES = DEFAULT == VALUES 916 | , VALUES_BUG = false 917 | , proto = Base.prototype 918 | , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT] 919 | , $default = $native || getMethod(DEFAULT) 920 | , $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined 921 | , $anyNative = NAME == 'Array' ? proto.entries || $native : $native 922 | , methods, key, IteratorPrototype; 923 | // Fix native 924 | if($anyNative){ 925 | IteratorPrototype = getPrototypeOf($anyNative.call(new Base)); 926 | if(IteratorPrototype !== Object.prototype){ 927 | // Set @@toStringTag to native iterators 928 | setToStringTag(IteratorPrototype, TAG, true); 929 | // fix for some old engines 930 | if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis); 931 | } 932 | } 933 | // fix Array#{values, @@iterator}.name in V8 / FF 934 | if(DEF_VALUES && $native && $native.name !== VALUES){ 935 | VALUES_BUG = true; 936 | $default = function values(){ return $native.call(this); }; 937 | } 938 | // Define iterator 939 | if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){ 940 | hide(proto, ITERATOR, $default); 941 | } 942 | // Plug for library 943 | Iterators[NAME] = $default; 944 | Iterators[TAG] = returnThis; 945 | if(DEFAULT){ 946 | methods = { 947 | values: DEF_VALUES ? $default : getMethod(VALUES), 948 | keys: IS_SET ? $default : getMethod(KEYS), 949 | entries: $entries 950 | }; 951 | if(FORCED)for(key in methods){ 952 | if(!(key in proto))redefine(proto, key, methods[key]); 953 | } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); 954 | } 955 | return methods; 956 | }; 957 | 958 | /***/ }, 959 | 960 | /***/ 435: 961 | /***/ function(module, exports) { 962 | 963 | module.exports = true; 964 | 965 | /***/ }, 966 | 967 | /***/ 436: 968 | /***/ function(module, exports, __webpack_require__) { 969 | 970 | module.exports = __webpack_require__(320); 971 | 972 | /***/ }, 973 | 974 | /***/ 437: 975 | /***/ function(module, exports) { 976 | 977 | module.exports = {}; 978 | 979 | /***/ }, 980 | 981 | /***/ 438: 982 | /***/ function(module, exports, __webpack_require__) { 983 | 984 | 'use strict'; 985 | var create = __webpack_require__(439) 986 | , descriptor = __webpack_require__(329) 987 | , setToStringTag = __webpack_require__(442) 988 | , IteratorPrototype = {}; 989 | 990 | // 25.1.2.1.1 %IteratorPrototype%[@@iterator]() 991 | __webpack_require__(320)(IteratorPrototype, __webpack_require__(443)('iterator'), function(){ return this; }); 992 | 993 | module.exports = function(Constructor, NAME, next){ 994 | Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)}); 995 | setToStringTag(Constructor, NAME + ' Iterator'); 996 | }; 997 | 998 | /***/ }, 999 | 1000 | /***/ 439: 1001 | /***/ function(module, exports, __webpack_require__) { 1002 | 1003 | // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) 1004 | var anObject = __webpack_require__(322) 1005 | , dPs = __webpack_require__(440) 1006 | , enumBugKeys = __webpack_require__(382) 1007 | , IE_PROTO = __webpack_require__(379)('IE_PROTO') 1008 | , Empty = function(){ /* empty */ } 1009 | , PROTOTYPE = 'prototype'; 1010 | 1011 | // Create object with fake `null` prototype: use iframe Object with cleared prototype 1012 | var createDict = function(){ 1013 | // Thrash, waste and sodomy: IE GC bug 1014 | var iframe = __webpack_require__(327)('iframe') 1015 | , i = enumBugKeys.length 1016 | , lt = '<' 1017 | , gt = '>' 1018 | , iframeDocument; 1019 | iframe.style.display = 'none'; 1020 | __webpack_require__(441).appendChild(iframe); 1021 | iframe.src = 'javascript:'; // eslint-disable-line no-script-url 1022 | // createDict = iframe.contentWindow.Object; 1023 | // html.removeChild(iframe); 1024 | iframeDocument = iframe.contentWindow.document; 1025 | iframeDocument.open(); 1026 | iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); 1027 | iframeDocument.close(); 1028 | createDict = iframeDocument.F; 1029 | while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]]; 1030 | return createDict(); 1031 | }; 1032 | 1033 | module.exports = Object.create || function create(O, Properties){ 1034 | var result; 1035 | if(O !== null){ 1036 | Empty[PROTOTYPE] = anObject(O); 1037 | result = new Empty; 1038 | Empty[PROTOTYPE] = null; 1039 | // add "__proto__" for Object.getPrototypeOf polyfill 1040 | result[IE_PROTO] = O; 1041 | } else result = createDict(); 1042 | return Properties === undefined ? result : dPs(result, Properties); 1043 | }; 1044 | 1045 | 1046 | /***/ }, 1047 | 1048 | /***/ 440: 1049 | /***/ function(module, exports, __webpack_require__) { 1050 | 1051 | var dP = __webpack_require__(321) 1052 | , anObject = __webpack_require__(322) 1053 | , getKeys = __webpack_require__(369); 1054 | 1055 | module.exports = __webpack_require__(325) ? Object.defineProperties : function defineProperties(O, Properties){ 1056 | anObject(O); 1057 | var keys = getKeys(Properties) 1058 | , length = keys.length 1059 | , i = 0 1060 | , P; 1061 | while(length > i)dP.f(O, P = keys[i++], Properties[P]); 1062 | return O; 1063 | }; 1064 | 1065 | /***/ }, 1066 | 1067 | /***/ 441: 1068 | /***/ function(module, exports, __webpack_require__) { 1069 | 1070 | module.exports = __webpack_require__(316).document && document.documentElement; 1071 | 1072 | /***/ }, 1073 | 1074 | /***/ 442: 1075 | /***/ function(module, exports, __webpack_require__) { 1076 | 1077 | var def = __webpack_require__(321).f 1078 | , has = __webpack_require__(371) 1079 | , TAG = __webpack_require__(443)('toStringTag'); 1080 | 1081 | module.exports = function(it, tag, stat){ 1082 | if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag}); 1083 | }; 1084 | 1085 | /***/ }, 1086 | 1087 | /***/ 443: 1088 | /***/ function(module, exports, __webpack_require__) { 1089 | 1090 | var store = __webpack_require__(380)('wks') 1091 | , uid = __webpack_require__(381) 1092 | , Symbol = __webpack_require__(316).Symbol 1093 | , USE_SYMBOL = typeof Symbol == 'function'; 1094 | 1095 | var $exports = module.exports = function(name){ 1096 | return store[name] || (store[name] = 1097 | USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); 1098 | }; 1099 | 1100 | $exports.store = store; 1101 | 1102 | /***/ }, 1103 | 1104 | /***/ 444: 1105 | /***/ function(module, exports, __webpack_require__) { 1106 | 1107 | // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) 1108 | var has = __webpack_require__(371) 1109 | , toObject = __webpack_require__(367) 1110 | , IE_PROTO = __webpack_require__(379)('IE_PROTO') 1111 | , ObjectProto = Object.prototype; 1112 | 1113 | module.exports = Object.getPrototypeOf || function(O){ 1114 | O = toObject(O); 1115 | if(has(O, IE_PROTO))return O[IE_PROTO]; 1116 | if(typeof O.constructor == 'function' && O instanceof O.constructor){ 1117 | return O.constructor.prototype; 1118 | } return O instanceof Object ? ObjectProto : null; 1119 | }; 1120 | 1121 | /***/ }, 1122 | 1123 | /***/ 445: 1124 | /***/ function(module, exports, __webpack_require__) { 1125 | 1126 | __webpack_require__(446); 1127 | var global = __webpack_require__(316) 1128 | , hide = __webpack_require__(320) 1129 | , Iterators = __webpack_require__(437) 1130 | , TO_STRING_TAG = __webpack_require__(443)('toStringTag'); 1131 | 1132 | for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){ 1133 | var NAME = collections[i] 1134 | , Collection = global[NAME] 1135 | , proto = Collection && Collection.prototype; 1136 | if(proto && !proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME); 1137 | Iterators[NAME] = Iterators.Array; 1138 | } 1139 | 1140 | /***/ }, 1141 | 1142 | /***/ 446: 1143 | /***/ function(module, exports, __webpack_require__) { 1144 | 1145 | 'use strict'; 1146 | var addToUnscopables = __webpack_require__(447) 1147 | , step = __webpack_require__(448) 1148 | , Iterators = __webpack_require__(437) 1149 | , toIObject = __webpack_require__(372); 1150 | 1151 | // 22.1.3.4 Array.prototype.entries() 1152 | // 22.1.3.13 Array.prototype.keys() 1153 | // 22.1.3.29 Array.prototype.values() 1154 | // 22.1.3.30 Array.prototype[@@iterator]() 1155 | module.exports = __webpack_require__(434)(Array, 'Array', function(iterated, kind){ 1156 | this._t = toIObject(iterated); // target 1157 | this._i = 0; // next index 1158 | this._k = kind; // kind 1159 | // 22.1.5.2.1 %ArrayIteratorPrototype%.next() 1160 | }, function(){ 1161 | var O = this._t 1162 | , kind = this._k 1163 | , index = this._i++; 1164 | if(!O || index >= O.length){ 1165 | this._t = undefined; 1166 | return step(1); 1167 | } 1168 | if(kind == 'keys' )return step(0, index); 1169 | if(kind == 'values')return step(0, O[index]); 1170 | return step(0, [index, O[index]]); 1171 | }, 'values'); 1172 | 1173 | // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) 1174 | Iterators.Arguments = Iterators.Array; 1175 | 1176 | addToUnscopables('keys'); 1177 | addToUnscopables('values'); 1178 | addToUnscopables('entries'); 1179 | 1180 | /***/ }, 1181 | 1182 | /***/ 447: 1183 | /***/ function(module, exports) { 1184 | 1185 | module.exports = function(){ /* empty */ }; 1186 | 1187 | /***/ }, 1188 | 1189 | /***/ 448: 1190 | /***/ function(module, exports) { 1191 | 1192 | module.exports = function(done, value){ 1193 | return {value: value, done: !!done}; 1194 | }; 1195 | 1196 | /***/ }, 1197 | 1198 | /***/ 449: 1199 | /***/ function(module, exports, __webpack_require__) { 1200 | 1201 | exports.f = __webpack_require__(443); 1202 | 1203 | /***/ }, 1204 | 1205 | /***/ 450: 1206 | /***/ function(module, exports, __webpack_require__) { 1207 | 1208 | module.exports = { "default": __webpack_require__(451), __esModule: true }; 1209 | 1210 | /***/ }, 1211 | 1212 | /***/ 451: 1213 | /***/ function(module, exports, __webpack_require__) { 1214 | 1215 | __webpack_require__(452); 1216 | __webpack_require__(461); 1217 | __webpack_require__(462); 1218 | __webpack_require__(463); 1219 | module.exports = __webpack_require__(317).Symbol; 1220 | 1221 | /***/ }, 1222 | 1223 | /***/ 452: 1224 | /***/ function(module, exports, __webpack_require__) { 1225 | 1226 | 'use strict'; 1227 | // ECMAScript 6 symbols shim 1228 | var global = __webpack_require__(316) 1229 | , has = __webpack_require__(371) 1230 | , DESCRIPTORS = __webpack_require__(325) 1231 | , $export = __webpack_require__(315) 1232 | , redefine = __webpack_require__(436) 1233 | , META = __webpack_require__(453).KEY 1234 | , $fails = __webpack_require__(326) 1235 | , shared = __webpack_require__(380) 1236 | , setToStringTag = __webpack_require__(442) 1237 | , uid = __webpack_require__(381) 1238 | , wks = __webpack_require__(443) 1239 | , wksExt = __webpack_require__(449) 1240 | , wksDefine = __webpack_require__(454) 1241 | , keyOf = __webpack_require__(455) 1242 | , enumKeys = __webpack_require__(456) 1243 | , isArray = __webpack_require__(457) 1244 | , anObject = __webpack_require__(322) 1245 | , toIObject = __webpack_require__(372) 1246 | , toPrimitive = __webpack_require__(328) 1247 | , createDesc = __webpack_require__(329) 1248 | , _create = __webpack_require__(439) 1249 | , gOPNExt = __webpack_require__(458) 1250 | , $GOPD = __webpack_require__(460) 1251 | , $DP = __webpack_require__(321) 1252 | , $keys = __webpack_require__(369) 1253 | , gOPD = $GOPD.f 1254 | , dP = $DP.f 1255 | , gOPN = gOPNExt.f 1256 | , $Symbol = global.Symbol 1257 | , $JSON = global.JSON 1258 | , _stringify = $JSON && $JSON.stringify 1259 | , PROTOTYPE = 'prototype' 1260 | , HIDDEN = wks('_hidden') 1261 | , TO_PRIMITIVE = wks('toPrimitive') 1262 | , isEnum = {}.propertyIsEnumerable 1263 | , SymbolRegistry = shared('symbol-registry') 1264 | , AllSymbols = shared('symbols') 1265 | , OPSymbols = shared('op-symbols') 1266 | , ObjectProto = Object[PROTOTYPE] 1267 | , USE_NATIVE = typeof $Symbol == 'function' 1268 | , QObject = global.QObject; 1269 | // Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 1270 | var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild; 1271 | 1272 | // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 1273 | var setSymbolDesc = DESCRIPTORS && $fails(function(){ 1274 | return _create(dP({}, 'a', { 1275 | get: function(){ return dP(this, 'a', {value: 7}).a; } 1276 | })).a != 7; 1277 | }) ? function(it, key, D){ 1278 | var protoDesc = gOPD(ObjectProto, key); 1279 | if(protoDesc)delete ObjectProto[key]; 1280 | dP(it, key, D); 1281 | if(protoDesc && it !== ObjectProto)dP(ObjectProto, key, protoDesc); 1282 | } : dP; 1283 | 1284 | var wrap = function(tag){ 1285 | var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]); 1286 | sym._k = tag; 1287 | return sym; 1288 | }; 1289 | 1290 | var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function(it){ 1291 | return typeof it == 'symbol'; 1292 | } : function(it){ 1293 | return it instanceof $Symbol; 1294 | }; 1295 | 1296 | var $defineProperty = function defineProperty(it, key, D){ 1297 | if(it === ObjectProto)$defineProperty(OPSymbols, key, D); 1298 | anObject(it); 1299 | key = toPrimitive(key, true); 1300 | anObject(D); 1301 | if(has(AllSymbols, key)){ 1302 | if(!D.enumerable){ 1303 | if(!has(it, HIDDEN))dP(it, HIDDEN, createDesc(1, {})); 1304 | it[HIDDEN][key] = true; 1305 | } else { 1306 | if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false; 1307 | D = _create(D, {enumerable: createDesc(0, false)}); 1308 | } return setSymbolDesc(it, key, D); 1309 | } return dP(it, key, D); 1310 | }; 1311 | var $defineProperties = function defineProperties(it, P){ 1312 | anObject(it); 1313 | var keys = enumKeys(P = toIObject(P)) 1314 | , i = 0 1315 | , l = keys.length 1316 | , key; 1317 | while(l > i)$defineProperty(it, key = keys[i++], P[key]); 1318 | return it; 1319 | }; 1320 | var $create = function create(it, P){ 1321 | return P === undefined ? _create(it) : $defineProperties(_create(it), P); 1322 | }; 1323 | var $propertyIsEnumerable = function propertyIsEnumerable(key){ 1324 | var E = isEnum.call(this, key = toPrimitive(key, true)); 1325 | if(this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return false; 1326 | return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true; 1327 | }; 1328 | var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){ 1329 | it = toIObject(it); 1330 | key = toPrimitive(key, true); 1331 | if(it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key))return; 1332 | var D = gOPD(it, key); 1333 | if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true; 1334 | return D; 1335 | }; 1336 | var $getOwnPropertyNames = function getOwnPropertyNames(it){ 1337 | var names = gOPN(toIObject(it)) 1338 | , result = [] 1339 | , i = 0 1340 | , key; 1341 | while(names.length > i){ 1342 | if(!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META)result.push(key); 1343 | } return result; 1344 | }; 1345 | var $getOwnPropertySymbols = function getOwnPropertySymbols(it){ 1346 | var IS_OP = it === ObjectProto 1347 | , names = gOPN(IS_OP ? OPSymbols : toIObject(it)) 1348 | , result = [] 1349 | , i = 0 1350 | , key; 1351 | while(names.length > i){ 1352 | if(has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true))result.push(AllSymbols[key]); 1353 | } return result; 1354 | }; 1355 | 1356 | // 19.4.1.1 Symbol([description]) 1357 | if(!USE_NATIVE){ 1358 | $Symbol = function Symbol(){ 1359 | if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor!'); 1360 | var tag = uid(arguments.length > 0 ? arguments[0] : undefined); 1361 | var $set = function(value){ 1362 | if(this === ObjectProto)$set.call(OPSymbols, value); 1363 | if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false; 1364 | setSymbolDesc(this, tag, createDesc(1, value)); 1365 | }; 1366 | if(DESCRIPTORS && setter)setSymbolDesc(ObjectProto, tag, {configurable: true, set: $set}); 1367 | return wrap(tag); 1368 | }; 1369 | redefine($Symbol[PROTOTYPE], 'toString', function toString(){ 1370 | return this._k; 1371 | }); 1372 | 1373 | $GOPD.f = $getOwnPropertyDescriptor; 1374 | $DP.f = $defineProperty; 1375 | __webpack_require__(459).f = gOPNExt.f = $getOwnPropertyNames; 1376 | __webpack_require__(424).f = $propertyIsEnumerable; 1377 | __webpack_require__(423).f = $getOwnPropertySymbols; 1378 | 1379 | if(DESCRIPTORS && !__webpack_require__(435)){ 1380 | redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true); 1381 | } 1382 | 1383 | wksExt.f = function(name){ 1384 | return wrap(wks(name)); 1385 | } 1386 | } 1387 | 1388 | $export($export.G + $export.W + $export.F * !USE_NATIVE, {Symbol: $Symbol}); 1389 | 1390 | for(var symbols = ( 1391 | // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14 1392 | 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables' 1393 | ).split(','), i = 0; symbols.length > i; )wks(symbols[i++]); 1394 | 1395 | for(var symbols = $keys(wks.store), i = 0; symbols.length > i; )wksDefine(symbols[i++]); 1396 | 1397 | $export($export.S + $export.F * !USE_NATIVE, 'Symbol', { 1398 | // 19.4.2.1 Symbol.for(key) 1399 | 'for': function(key){ 1400 | return has(SymbolRegistry, key += '') 1401 | ? SymbolRegistry[key] 1402 | : SymbolRegistry[key] = $Symbol(key); 1403 | }, 1404 | // 19.4.2.5 Symbol.keyFor(sym) 1405 | keyFor: function keyFor(key){ 1406 | if(isSymbol(key))return keyOf(SymbolRegistry, key); 1407 | throw TypeError(key + ' is not a symbol!'); 1408 | }, 1409 | useSetter: function(){ setter = true; }, 1410 | useSimple: function(){ setter = false; } 1411 | }); 1412 | 1413 | $export($export.S + $export.F * !USE_NATIVE, 'Object', { 1414 | // 19.1.2.2 Object.create(O [, Properties]) 1415 | create: $create, 1416 | // 19.1.2.4 Object.defineProperty(O, P, Attributes) 1417 | defineProperty: $defineProperty, 1418 | // 19.1.2.3 Object.defineProperties(O, Properties) 1419 | defineProperties: $defineProperties, 1420 | // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) 1421 | getOwnPropertyDescriptor: $getOwnPropertyDescriptor, 1422 | // 19.1.2.7 Object.getOwnPropertyNames(O) 1423 | getOwnPropertyNames: $getOwnPropertyNames, 1424 | // 19.1.2.8 Object.getOwnPropertySymbols(O) 1425 | getOwnPropertySymbols: $getOwnPropertySymbols 1426 | }); 1427 | 1428 | // 24.3.2 JSON.stringify(value [, replacer [, space]]) 1429 | $JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function(){ 1430 | var S = $Symbol(); 1431 | // MS Edge converts symbol values to JSON as {} 1432 | // WebKit converts symbol values to JSON as null 1433 | // V8 throws on boxed symbols 1434 | return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}'; 1435 | })), 'JSON', { 1436 | stringify: function stringify(it){ 1437 | if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined 1438 | var args = [it] 1439 | , i = 1 1440 | , replacer, $replacer; 1441 | while(arguments.length > i)args.push(arguments[i++]); 1442 | replacer = args[1]; 1443 | if(typeof replacer == 'function')$replacer = replacer; 1444 | if($replacer || !isArray(replacer))replacer = function(key, value){ 1445 | if($replacer)value = $replacer.call(this, key, value); 1446 | if(!isSymbol(value))return value; 1447 | }; 1448 | args[1] = replacer; 1449 | return _stringify.apply($JSON, args); 1450 | } 1451 | }); 1452 | 1453 | // 19.4.3.4 Symbol.prototype[@@toPrimitive](hint) 1454 | $Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(320)($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf); 1455 | // 19.4.3.5 Symbol.prototype[@@toStringTag] 1456 | setToStringTag($Symbol, 'Symbol'); 1457 | // 20.2.1.9 Math[@@toStringTag] 1458 | setToStringTag(Math, 'Math', true); 1459 | // 24.3.3 JSON[@@toStringTag] 1460 | setToStringTag(global.JSON, 'JSON', true); 1461 | 1462 | /***/ }, 1463 | 1464 | /***/ 453: 1465 | /***/ function(module, exports, __webpack_require__) { 1466 | 1467 | var META = __webpack_require__(381)('meta') 1468 | , isObject = __webpack_require__(323) 1469 | , has = __webpack_require__(371) 1470 | , setDesc = __webpack_require__(321).f 1471 | , id = 0; 1472 | var isExtensible = Object.isExtensible || function(){ 1473 | return true; 1474 | }; 1475 | var FREEZE = !__webpack_require__(326)(function(){ 1476 | return isExtensible(Object.preventExtensions({})); 1477 | }); 1478 | var setMeta = function(it){ 1479 | setDesc(it, META, {value: { 1480 | i: 'O' + ++id, // object ID 1481 | w: {} // weak collections IDs 1482 | }}); 1483 | }; 1484 | var fastKey = function(it, create){ 1485 | // return primitive with prefix 1486 | if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; 1487 | if(!has(it, META)){ 1488 | // can't set metadata to uncaught frozen object 1489 | if(!isExtensible(it))return 'F'; 1490 | // not necessary to add metadata 1491 | if(!create)return 'E'; 1492 | // add missing metadata 1493 | setMeta(it); 1494 | // return object ID 1495 | } return it[META].i; 1496 | }; 1497 | var getWeak = function(it, create){ 1498 | if(!has(it, META)){ 1499 | // can't set metadata to uncaught frozen object 1500 | if(!isExtensible(it))return true; 1501 | // not necessary to add metadata 1502 | if(!create)return false; 1503 | // add missing metadata 1504 | setMeta(it); 1505 | // return hash weak collections IDs 1506 | } return it[META].w; 1507 | }; 1508 | // add metadata on freeze-family methods calling 1509 | var onFreeze = function(it){ 1510 | if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it); 1511 | return it; 1512 | }; 1513 | var meta = module.exports = { 1514 | KEY: META, 1515 | NEED: false, 1516 | fastKey: fastKey, 1517 | getWeak: getWeak, 1518 | onFreeze: onFreeze 1519 | }; 1520 | 1521 | /***/ }, 1522 | 1523 | /***/ 454: 1524 | /***/ function(module, exports, __webpack_require__) { 1525 | 1526 | var global = __webpack_require__(316) 1527 | , core = __webpack_require__(317) 1528 | , LIBRARY = __webpack_require__(435) 1529 | , wksExt = __webpack_require__(449) 1530 | , defineProperty = __webpack_require__(321).f; 1531 | module.exports = function(name){ 1532 | var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {}); 1533 | if(name.charAt(0) != '_' && !(name in $Symbol))defineProperty($Symbol, name, {value: wksExt.f(name)}); 1534 | }; 1535 | 1536 | /***/ }, 1537 | 1538 | /***/ 455: 1539 | /***/ function(module, exports, __webpack_require__) { 1540 | 1541 | var getKeys = __webpack_require__(369) 1542 | , toIObject = __webpack_require__(372); 1543 | module.exports = function(object, el){ 1544 | var O = toIObject(object) 1545 | , keys = getKeys(O) 1546 | , length = keys.length 1547 | , index = 0 1548 | , key; 1549 | while(length > index)if(O[key = keys[index++]] === el)return key; 1550 | }; 1551 | 1552 | /***/ }, 1553 | 1554 | /***/ 456: 1555 | /***/ function(module, exports, __webpack_require__) { 1556 | 1557 | // all enumerable object keys, includes symbols 1558 | var getKeys = __webpack_require__(369) 1559 | , gOPS = __webpack_require__(423) 1560 | , pIE = __webpack_require__(424); 1561 | module.exports = function(it){ 1562 | var result = getKeys(it) 1563 | , getSymbols = gOPS.f; 1564 | if(getSymbols){ 1565 | var symbols = getSymbols(it) 1566 | , isEnum = pIE.f 1567 | , i = 0 1568 | , key; 1569 | while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))result.push(key); 1570 | } return result; 1571 | }; 1572 | 1573 | /***/ }, 1574 | 1575 | /***/ 457: 1576 | /***/ function(module, exports, __webpack_require__) { 1577 | 1578 | // 7.2.2 IsArray(argument) 1579 | var cof = __webpack_require__(374); 1580 | module.exports = Array.isArray || function isArray(arg){ 1581 | return cof(arg) == 'Array'; 1582 | }; 1583 | 1584 | /***/ }, 1585 | 1586 | /***/ 458: 1587 | /***/ function(module, exports, __webpack_require__) { 1588 | 1589 | // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window 1590 | var toIObject = __webpack_require__(372) 1591 | , gOPN = __webpack_require__(459).f 1592 | , toString = {}.toString; 1593 | 1594 | var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames 1595 | ? Object.getOwnPropertyNames(window) : []; 1596 | 1597 | var getWindowNames = function(it){ 1598 | try { 1599 | return gOPN(it); 1600 | } catch(e){ 1601 | return windowNames.slice(); 1602 | } 1603 | }; 1604 | 1605 | module.exports.f = function getOwnPropertyNames(it){ 1606 | return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it)); 1607 | }; 1608 | 1609 | 1610 | /***/ }, 1611 | 1612 | /***/ 459: 1613 | /***/ function(module, exports, __webpack_require__) { 1614 | 1615 | // 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O) 1616 | var $keys = __webpack_require__(370) 1617 | , hiddenKeys = __webpack_require__(382).concat('length', 'prototype'); 1618 | 1619 | exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){ 1620 | return $keys(O, hiddenKeys); 1621 | }; 1622 | 1623 | /***/ }, 1624 | 1625 | /***/ 460: 1626 | /***/ function(module, exports, __webpack_require__) { 1627 | 1628 | var pIE = __webpack_require__(424) 1629 | , createDesc = __webpack_require__(329) 1630 | , toIObject = __webpack_require__(372) 1631 | , toPrimitive = __webpack_require__(328) 1632 | , has = __webpack_require__(371) 1633 | , IE8_DOM_DEFINE = __webpack_require__(324) 1634 | , gOPD = Object.getOwnPropertyDescriptor; 1635 | 1636 | exports.f = __webpack_require__(325) ? gOPD : function getOwnPropertyDescriptor(O, P){ 1637 | O = toIObject(O); 1638 | P = toPrimitive(P, true); 1639 | if(IE8_DOM_DEFINE)try { 1640 | return gOPD(O, P); 1641 | } catch(e){ /* empty */ } 1642 | if(has(O, P))return createDesc(!pIE.f.call(O, P), O[P]); 1643 | }; 1644 | 1645 | /***/ }, 1646 | 1647 | /***/ 461: 1648 | /***/ function(module, exports) { 1649 | 1650 | 1651 | 1652 | /***/ }, 1653 | 1654 | /***/ 462: 1655 | /***/ function(module, exports, __webpack_require__) { 1656 | 1657 | __webpack_require__(454)('asyncIterator'); 1658 | 1659 | /***/ }, 1660 | 1661 | /***/ 463: 1662 | /***/ function(module, exports, __webpack_require__) { 1663 | 1664 | __webpack_require__(454)('observable'); 1665 | 1666 | /***/ } 1667 | 1668 | /******/ }); -------------------------------------------------------------------------------- /docs/sb-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ui-storybook/sb/d6a8247720b5b1271f2f4233cd37656b41cff0b1/docs/sb-demo.gif -------------------------------------------------------------------------------- /gulpfile.babel.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import gulp from 'gulp'; 4 | import webpack from 'webpack'; 5 | import path from 'path'; 6 | import sync from 'run-sequence'; 7 | import rename from 'gulp-rename'; 8 | import template from 'gulp-template'; 9 | import fs from 'fs'; 10 | import yargs from 'yargs'; 11 | import lodash from 'lodash'; 12 | import gutil from 'gulp-util'; 13 | import serve from 'browser-sync'; 14 | import del from 'del'; 15 | import webpackDevMiddleware from 'webpack-dev-middleware'; 16 | import webpackHotMiddleware from 'webpack-hot-middleware'; 17 | import colorsSupported from 'supports-color'; 18 | import historyApiFallback from 'connect-history-api-fallback'; 19 | 20 | let root = 'src'; 21 | 22 | // helper method for resolving paths 23 | let resolveToApp = (glob = '') => { 24 | return path.join(root, 'app', glob); // app/{glob} 25 | }; 26 | 27 | let resolveToComponents = (glob = '') => { 28 | return path.join(root, 'app/components', glob); // app/components/{glob} 29 | }; 30 | 31 | let resolveToModules = (glob = '') => { 32 | return path.join(root, 'app/modules', glob); // app/modules/{glob} 33 | }; 34 | 35 | // map of all paths 36 | let paths = { 37 | js: resolveToComponents('**/*!(.spec.js).js'), // exclude spec files 38 | styl: resolveToApp('**/*.styl'), // stylesheets 39 | html: [ 40 | resolveToApp('**/*.html'), 41 | path.join(root, 'index.html') 42 | ], 43 | entry: [ 44 | 'babel-polyfill', 45 | path.join(__dirname, root, 'app/index.js') 46 | ], 47 | output: root, 48 | blankTemplates: { 49 | component: path.join(__dirname, 'generator', 'component/**/*.**'), 50 | module: path.join(__dirname, 'generator', 'module/**/*.**'), 51 | }, 52 | dest: path.join(__dirname, 'dist') 53 | }; 54 | 55 | // use webpack.config.js to build modules 56 | gulp.task('build', ['clean'], (cb) => { 57 | const config = require('./webpack.dist.config'); 58 | config.entry.app = paths.entry; 59 | 60 | webpack(config, (err, stats) => { 61 | if(err) { 62 | throw new gutil.PluginError("webpack", err); 63 | } 64 | 65 | gutil.log("[webpack]", stats.toString({ 66 | colors: colorsSupported, 67 | chunks: false, 68 | errorDetails: true 69 | })); 70 | 71 | cb(); 72 | }); 73 | }); 74 | 75 | gulp.task('serve', () => { 76 | const config = require('./webpack.dev.config'); 77 | config.entry.app = [ 78 | // this modules required to make HRM working 79 | // it responsible for all this webpack magic 80 | 'webpack-hot-middleware?reload=true', 81 | // application entry point 82 | ].concat(paths.entry); 83 | 84 | var compiler = webpack(config); 85 | 86 | serve({ 87 | port: process.env.PORT || 3000, 88 | open: false, 89 | server: {baseDir: root}, 90 | middleware: [ 91 | historyApiFallback(), 92 | webpackDevMiddleware(compiler, { 93 | stats: { 94 | colors: colorsSupported, 95 | chunks: false, 96 | modules: false 97 | }, 98 | publicPath: config.output.publicPath 99 | }), 100 | webpackHotMiddleware(compiler) 101 | ] 102 | }); 103 | }); 104 | 105 | gulp.task('watch', ['serve']); 106 | 107 | gulp.task('clean', (cb) => { 108 | del([paths.dest]).then(function (paths) { 109 | gutil.log("[clean]", paths); 110 | cb(); 111 | }) 112 | }); 113 | 114 | gulp.task('default', ['watch']); 115 | -------------------------------------------------------------------------------- /helpers/ng.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../dist/ng-helper'); -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function (config) { 2 | config.set({ 3 | // base path used to resolve all patterns 4 | basePath: '/', 5 | 6 | // frameworks to use 7 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 8 | frameworks: ['mocha', 'chai'], 9 | 10 | // list of files/patterns to load in the browser 11 | files: [{ pattern: 'spec.`bundle`.js', watched: false }], 12 | 13 | // files to exclude 14 | exclude: [], 15 | 16 | plugins: [ 17 | require("karma-chai"), 18 | require("karma-chrome-launcher"), 19 | require("karma-mocha"), 20 | require("karma-mocha-reporter"), 21 | require("karma-sourcemap-loader"), 22 | require("karma-webpack") 23 | ], 24 | 25 | // preprocess matching files before serving them to the browser 26 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 27 | preprocessors: { 'spec.bundle.js': ['webpack', 'sourcemap'] }, 28 | 29 | webpack: { 30 | devtool: 'inline-source-map', 31 | module: { 32 | loaders: [ 33 | { test: /\.js/, exclude: [/app\/lib/, /node_modules/], loader: 'babel' }, 34 | { test: /\.html/, loader: 'raw' }, 35 | { test: /\.styl$/, loader: 'style!css!stylus' }, 36 | { test: /\.css$/, loader: 'style!css' } 37 | ] 38 | } 39 | }, 40 | 41 | webpackServer: { 42 | noInfo: true // prevent console spamming when running in Karma! 43 | }, 44 | 45 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 46 | reporters: ['mocha'], 47 | 48 | // web server port 49 | port: 9876, 50 | 51 | // enable colors in the output 52 | colors: true, 53 | 54 | // level of logging 55 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 56 | logLevel: config.LOG_INFO, 57 | 58 | // toggle whether to watch files and rerun tests upon incurring changes 59 | autoWatch: false, 60 | 61 | // start these browsers 62 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 63 | browsers: ['Chrome'], 64 | 65 | // if true, Karma runs tests once and exits 66 | singleRun: true 67 | }); 68 | }; 69 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ui-storybook", 3 | "version": "1.3.0", 4 | "description": "SB is the environment for developers that allow to esaly develop and support UI components with any framework.", 5 | "main": "index.js", 6 | "types": "./src/sb.d.ts", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/ui-storybook/sb" 10 | }, 11 | "dependencies": { 12 | "angular-sanitize": "1.5", 13 | "jsonformatter": "^0.6.0" 14 | }, 15 | "devDependencies": { 16 | "ace-builds": "*", 17 | "angular-animate": "*", 18 | "angular-aria": "*", 19 | "angular-dnd-module": "*", 20 | "angular-material": "*", 21 | "angular-mocks": "*", 22 | "angular-resizable": "*", 23 | "angular-sanitize": "*", 24 | "angular-ui-ace": "*", 25 | "angular-ui-codemirror": "*", 26 | "angular-ui-router": "*", 27 | "babel-core": "*", 28 | "babel-loader": "*", 29 | "babel-plugin-transform-runtime": "*", 30 | "babel-polyfill": "*", 31 | "babel-preset-es2015": "*", 32 | "babel-preset-stage-0": "*", 33 | "babel-register": "*", 34 | "babel-runtime": "*", 35 | "browser-sync": "*", 36 | "chai": "*", 37 | "commitizen": "^2.8.6", 38 | "connect-history-api-fallback": "*", 39 | "css-loader": "*", 40 | "cz-conventional-changelog": "^1.2.0", 41 | "del": "*", 42 | "fs-walk": "*", 43 | "git-url-parse": "*", 44 | "gulp": "*", 45 | "gulp-rename": "*", 46 | "gulp-template": "*", 47 | "gulp-util": "*", 48 | "html-loader": "^0.5.1", 49 | "html-webpack-plugin": "*", 50 | "karma": "*", 51 | "karma-chai": "*", 52 | "karma-chrome-launcher": "*", 53 | "karma-mocha": "*", 54 | "karma-mocha-reporter": "*", 55 | "karma-sourcemap-loader": "*", 56 | "karma-webpack": "*", 57 | "less": "*", 58 | "less-loader": "*", 59 | "lodash": "*", 60 | "markdown-loader": "^2.0.1", 61 | "mocha": "*", 62 | "ng-annotate-loader": "*", 63 | "node-libs-browser": "*", 64 | "normalize.css": "*", 65 | "raw-loader": "*", 66 | "run-sequence": "*", 67 | "semantic-release": "^4.3.5", 68 | "shelljs": "*", 69 | "style-loader": "*", 70 | "stylus": "*", 71 | "stylus-loader": "*", 72 | "supports-color": "*", 73 | "webpack": "*", 74 | "webpack-dev-middleware": "*", 75 | "webpack-hot-middleware": "*", 76 | "yargs": "*" 77 | }, 78 | "scripts": { 79 | "start": "gulp serve", 80 | "build": "gulp build", 81 | "commit": "git-cz", 82 | "semantic-release": "semantic-release pre && npm publish && semantic-release post" 83 | }, 84 | "config": { 85 | "commitizen": { 86 | "path": "node_modules/cz-conventional-changelog" 87 | } 88 | }, 89 | "author": "freeman14" 90 | } -------------------------------------------------------------------------------- /sb.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/sb'); -------------------------------------------------------------------------------- /spec.bundle.js: -------------------------------------------------------------------------------- 1 | /* 2 | * When testing with Webpack and ES6, we have to do some 3 | * preliminary setup. Because we are writing our tests also in ES6, 4 | * we must transpile those as well, which is handled inside 5 | * `karma.conf.js` via the `karma-webpack` plugin. This is the entry 6 | * file for the Webpack tests. Similarly to how Webpack creates a 7 | * `bundle.js` file for the compressed app source files, when we 8 | * run our tests, Webpack, likewise, compiles and bundles those tests here. 9 | */ 10 | 11 | import angular from 'angular'; 12 | 13 | // Built by the core Angular team for mocking dependencies 14 | import mocks from 'angular-mocks'; 15 | 16 | // We use the context method on `require` which Webpack created 17 | // in order to signify which files we actually want to require or import. 18 | // Below, `context` will be a/an function/object with file names as keys. 19 | // Using that regex, we scan within `client/app` and target 20 | // all files ending with `.spec.js` and trace its path. 21 | // By passing in true, we permit this process to occur recursively. 22 | let context = require.context('./client/app', true, /\.spec\.js/); 23 | 24 | // Get all files, for each file, call the context function 25 | // that will require the file and load it here. Context will 26 | // loop and require those spec files here. 27 | context.keys().forEach(context); 28 | -------------------------------------------------------------------------------- /src/app/components/components.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | const module = angular.module('components', []); 3 | 4 | module.component('test', { 5 | controller: function($http) { 6 | $http.get('https://randomuser.me/api/'); 7 | }, 8 | template: `
{{$ctrl.text}}
`, 9 | bindings: { 10 | text: '@' 11 | } 12 | }); 13 | 14 | export default module.name; 15 | -------------------------------------------------------------------------------- /src/app/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import './style.less' 3 | import helper from '../helpers/angular/helper' 4 | import components from './components/components'; 5 | 6 | angular.module('sb.stories', [helper, components]); 7 | 8 | let preview = document.createElement('preview-helper'); 9 | document.body.appendChild(preview); 10 | 11 | angular.element(preview) 12 | .ready(() => { 13 | angular.bootstrap(preview, ['sb.stories'], { strictDi: false }); 14 | }); -------------------------------------------------------------------------------- /src/app/style.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ui-storybook/sb/d6a8247720b5b1271f2f4233cd37656b41cff0b1/src/app/style.less -------------------------------------------------------------------------------- /src/helpers/angular/helper.compile.js: -------------------------------------------------------------------------------- 1 | export default $compile => (scope, element, attrs) => { 2 | scope.$watch( 3 | scope => scope.$eval(attrs.compile), 4 | value => { 5 | element.html(value); 6 | $compile(element.contents())(scope); 7 | } 8 | ); 9 | }; -------------------------------------------------------------------------------- /src/helpers/angular/helper.controller.js: -------------------------------------------------------------------------------- 1 | class HelperController { 2 | 3 | constructor($scope, SBInterceptor) { 4 | this.$scope = $scope; 5 | 6 | // Allowed events from parrent iFrame 7 | this.events = { 8 | 'component': this.loadComponent, 9 | 'model': this.loadModel 10 | } 11 | } 12 | 13 | $onInit() { 14 | 15 | // Tell sb that helper already loaded; 16 | window.parent.sb.contact(); 17 | 18 | // Register lissener for render new component 19 | this.postMessageListener = window.addEventListener('message', event => { 20 | event.data && this.events[event.data.type].call(this, event.data); 21 | }, false); 22 | 23 | } 24 | 25 | $onDestroy() { 26 | this.postMessageListener(); 27 | } 28 | 29 | loadModel(model) { 30 | if (model) { 31 | for (let k in model) { 32 | this[k] = model[k]; 33 | } 34 | } 35 | this.$scope.$apply(); 36 | } 37 | 38 | loadComponent(entity) { 39 | let component = window.parent.sb.getStory(entity.data); 40 | this.template = component.template; 41 | if (component.model) { 42 | for (let k in component.model) { 43 | this[k] = component.model[k]; 44 | } 45 | } 46 | this.$scope.$apply(); 47 | } 48 | 49 | } 50 | 51 | export default HelperController; -------------------------------------------------------------------------------- /src/helpers/angular/helper.js: -------------------------------------------------------------------------------- 1 | import 'angular-sanitize'; 2 | import controller from './helper.controller'; 3 | import compile from './helper.compile'; 4 | import interceptor from './interceptor.service'; 5 | 6 | let module = angular.module('helper', ['ngSanitize']); 7 | 8 | module.service('SBInterceptor', interceptor); 9 | 10 | module.directive('compile', compile); 11 | 12 | module.component('previewHelper', { 13 | controller, 14 | template: `
`, 15 | controllerAs: 'vm' 16 | }); 17 | 18 | export default module.name; -------------------------------------------------------------------------------- /src/helpers/angular/interceptor.service.js: -------------------------------------------------------------------------------- 1 | class InterceptorController { 2 | 3 | constructor() { 4 | this.requests = {}; 5 | this.updateXHROpenMethod(); 6 | } 7 | 8 | updateXHROpenMethod() { 9 | let self = this; 10 | this.origOpen = XMLHttpRequest.prototype.open; 11 | XMLHttpRequest.prototype.open = function(type, url) { 12 | 13 | // Skip request to browser-sync 14 | if (url.indexOf('browser-sync/socket.io') === -1) { 15 | const id = self.generateID(); 16 | const inProgress = true; 17 | let request = { type, url, inProgress, id }; 18 | 19 | self.sendRequestToSB(request); 20 | 21 | this.addEventListener('load', function() { 22 | try { 23 | request.responce = JSON.parse(this.responseText); 24 | } catch (e) { } 25 | request.status = this.status; 26 | request.statusText = this.statusText; 27 | request.inProgress = false; 28 | self.sendRequestToSB(request, 'update'); 29 | }); 30 | } 31 | 32 | self.origOpen.apply(this, arguments); 33 | }; 34 | } 35 | 36 | sendRequestToSB(request) { 37 | const message = 'xhr'; 38 | window.parent.postMessage({ message, request }, '*'); 39 | } 40 | 41 | generateID() { 42 | return Math.random().toString(36).substr(2, 10); 43 | } 44 | 45 | } 46 | 47 | export default InterceptorController; 48 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Angular Storybook 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/preview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | UI storybook 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/sb.d.ts: -------------------------------------------------------------------------------- 1 | declare var sb: stotybook.ISB; 2 | 3 | declare namespace stotybook { 4 | 5 | interface ISB { 6 | /** 7 | * Use this method to create new section(page) 8 | * 9 | * @param name The name of section 10 | */ 11 | section(name: string): ISection; 12 | } 13 | 14 | interface ISection { 15 | /** 16 | * Use this method to create new story point 17 | * for section 18 | * 19 | * @param name The name of story 20 | */ 21 | story(name: string): IStory; 22 | } 23 | 24 | interface IStory { 25 | /** 26 | * Use this method to add new states for story 27 | * 28 | * @param title Title of component 29 | * @param template Template witch need to render 30 | * @param model Object witch need to include into component scope 31 | */ 32 | add( 33 | title: string, 34 | template: string, 35 | model: Object ): IStory; 36 | } 37 | 38 | } 39 | 40 | declare var SBNGHelper: any; -------------------------------------------------------------------------------- /src/sb/app.module.js: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import core from './core/core.module'; 4 | import services from './services/services.module'; 5 | import modules from './modules/modules.module'; 6 | import components from './components/components.module'; 7 | import directives from './directives/directives.module'; 8 | 9 | angular.module('sb', [ 10 | 'sb.core', 11 | 'sb.modules', 12 | 'sb.directives', 13 | 'sb.directives', 14 | 'sb.services', 15 | 'sb.components' 16 | ]); 17 | -------------------------------------------------------------------------------- /src/sb/components/components.module.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import 'angular-ui-router'; 3 | 4 | import previewComponent from './preview/preview.component'; 5 | import storyListComponent from './storyList/storyList.component'; 6 | import templateComponent from './template/template.component'; 7 | import modelComponent from './model/model.component' 8 | import interceptorComponent from './interceptor/interceptor.component' 9 | import markdownComponent from './markdown/markdown.component' 10 | 11 | const module = angular.module('sb.components', ['ui.router',]); 12 | 13 | module.component('preview', previewComponent); 14 | module.component('storyList', storyListComponent); 15 | module.component('model', modelComponent); 16 | module.component('view', templateComponent); 17 | module.component('interceptor', interceptorComponent); 18 | module.component('markdown', markdownComponent); 19 | 20 | module.run(storeService => { 21 | 22 | const tabs = [ 23 | { 24 | title: 'preview', 25 | template: '' 26 | }, 27 | { 28 | title: 'model', 29 | template: '' 30 | }, 31 | { 32 | title: 'view', 33 | template: '' 34 | }, 35 | { 36 | title: 'XHR', 37 | template: '' 38 | }, 39 | { 40 | title: 'Docs', 41 | template: '' 42 | } 43 | ]; 44 | 45 | // Register tabs 46 | tabs.forEach(tab => storeService.component(tab)); 47 | 48 | }); 49 | 50 | export default module; 51 | -------------------------------------------------------------------------------- /src/sb/components/interceptor/interceptor.component.js: -------------------------------------------------------------------------------- 1 | import template from './interceptor.html'; 2 | import controller from './interceptor.controller'; 3 | import './interceptor.less'; 4 | 5 | let interceptorComponent = { 6 | bindings: {}, 7 | controllerAs: 'vm', 8 | template, 9 | controller 10 | }; 11 | 12 | export default interceptorComponent; 13 | -------------------------------------------------------------------------------- /src/sb/components/interceptor/interceptor.controller.js: -------------------------------------------------------------------------------- 1 | class InterceptorController { 2 | constructor($scope) { 3 | this.$scope = $scope; 4 | this.requests = {}; 5 | 6 | const eventMethod = window.addEventListener ? "addEventListener" : "attachEvent"; 7 | const eventer = window[eventMethod]; 8 | const messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message"; 9 | 10 | eventer(messageEvent, (e) => { 11 | if (e.data.message === 'xhr') { 12 | this.updateResponce(e.data); 13 | } 14 | }, false); 15 | } 16 | 17 | updateResponce(data) { 18 | this.requests[data.request.id] = data.request; 19 | this.$scope.$apply(); 20 | } 21 | 22 | copyResponce($event, responce) { 23 | window.prompt("Copy to clipboard: CMD(Ctrl)+C, Enter", JSON.stringify(responce)); 24 | $event.stopImmediatePropagation(); 25 | } 26 | 27 | openRequest(request) { 28 | if (request.selected) { 29 | this.activeRequest.selected = false; 30 | return; 31 | } 32 | if (this.activeRequest) { 33 | this.activeRequest.selected = false; 34 | } 35 | this.activeRequest = request; 36 | this.activeRequest.selected = true; 37 | } 38 | 39 | } 40 | 41 | export default InterceptorController; 42 | -------------------------------------------------------------------------------- /src/sb/components/interceptor/interceptor.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 |
6 |
7 |
8 | Copy responce 9 |
10 |
11 | 12 |
13 | 14 |
15 |
16 |
-------------------------------------------------------------------------------- /src/sb/components/interceptor/interceptor.less: -------------------------------------------------------------------------------- 1 | .split__active interceptor { 2 | border-left: 1px solid rgba(0, 0, 0, 0.14); 3 | overflow: scroll; 4 | } 5 | 6 | interceptor { 7 | background: #fff; 8 | 9 | * { 10 | outline: none; 11 | } 12 | 13 | } 14 | 15 | .request__close .md-subheader-wrapper{ 16 | display: none !important; 17 | } 18 | 19 | .interceptors__list { 20 | font-size: 13px; 21 | border-bottom: 1px solid rgba(0, 0, 0, 0.07); 22 | background: #fff; 23 | 24 | .md-subheader .md-subheader-inner { 25 | padding: 0; 26 | } 27 | 28 | .md-subheader { 29 | background: #fff; 30 | } 31 | 32 | } 33 | 34 | .md-subheader-inner { 35 | padding: 0 !important; 36 | } 37 | 38 | .request__info { 39 | outline: none; 40 | height: 50px; 41 | cursor: pointer; 42 | position: relative; 43 | 44 | &:hover { 45 | .request__copy { 46 | display: block; 47 | position: absolute; 48 | right: 16px; 49 | top: 1px; 50 | } 51 | } 52 | 53 | .request__copy { 54 | display: none; 55 | } 56 | 57 | 58 | 59 | .request__url { 60 | white-space: nowrap; 61 | overflow: hidden; 62 | text-overflow: ellipsis; 63 | } 64 | 65 | } 66 | 67 | .request__responce { 68 | padding: 15px 28px; 69 | font-size: 14px; 70 | } 71 | 72 | .theme( 73 | @default-color: black, 74 | @string-color: green, 75 | @number-color: blue, 76 | @boolean-color: red, 77 | @null-color: #855A00, 78 | @undefined-color: rgb(202, 11, 105), 79 | @function-color: #FF20ED, 80 | @rotate-time: 100ms, 81 | @toggler-opacity: 0.6, 82 | @toggler-color: #45376F, 83 | @bracket-color: blue, 84 | @key-color: #00008B, 85 | @url-color: blue ){ 86 | 87 | font-family: monospace; 88 | &, a, a:hover { 89 | color: @default-color; 90 | text-decoration: none; 91 | } 92 | 93 | .json-formatter-row { 94 | margin-left: 1em; 95 | padding: 5px 0; 96 | } 97 | 98 | .children { 99 | &.empty { 100 | opacity: 0.5; 101 | margin-left: 1em; 102 | 103 | &.object:after { content: "No properties"; } 104 | &.array:after { content: "[]"; } 105 | } 106 | } 107 | 108 | .string { 109 | color: @string-color; 110 | word-wrap: break-word; 111 | } 112 | .number { color: @number-color; } 113 | .boolean { color: @boolean-color; } 114 | .null { color: @null-color; } 115 | .undefined { color: @undefined-color; } 116 | .function { color: @function-color; } 117 | .date { background-color: fade(@default-color, 5%); } 118 | .url { 119 | text-decoration: underline; 120 | color: @url-color; 121 | cursor: pointer; 122 | } 123 | 124 | .bracket { color: @bracket-color; } 125 | .key { 126 | color: @key-color; 127 | cursor: pointer; 128 | } 129 | .constructor-name { 130 | cursor: pointer; 131 | } 132 | 133 | .toggler { 134 | font-size: 0.8em; 135 | line-height: 1.2em; 136 | vertical-align: middle; 137 | opacity: 0.6; 138 | cursor: pointer; 139 | 140 | &:after { 141 | display: inline-block; 142 | content: "►"; 143 | } 144 | 145 | &.open:after{ 146 | transform: rotate(90deg); 147 | } 148 | } 149 | 150 | > a >.thumbnail-text { 151 | opacity: 0; 152 | transition: opacity .15s ease-in; 153 | font-style: italic; 154 | } 155 | 156 | &:hover > a > .thumbnail-text { 157 | opacity: 0.6; 158 | } 159 | } 160 | 161 | 162 | .json-formatter-row { 163 | .theme(); 164 | } 165 | 166 | .json-formatter-dark.json-formatter-row { 167 | .theme( 168 | @default-color: white, 169 | @string-color: #31F031, 170 | @number-color: #66C2FF, 171 | @boolean-color: #EC4242, 172 | @null-color: #EEC97D, 173 | @undefined-color: rgb(239, 143, 190), 174 | @function-color: #FD48CB, 175 | @rotate-time: 100ms, 176 | @toggler-opacity: 0.6, 177 | @toggler-color: #45376F, 178 | @bracket-color: #9494FF, 179 | @key-color: #23A0DB, 180 | @url-color: #027BFF); 181 | } -------------------------------------------------------------------------------- /src/sb/components/markdown/markdown.component.js: -------------------------------------------------------------------------------- 1 | import template from './markdown.html'; 2 | import controller from './markdown.controller'; 3 | import './markdown.less'; 4 | 5 | let markdownComponent = { 6 | bindings: {}, 7 | controllerAs: 'vm', 8 | template, 9 | controller 10 | }; 11 | 12 | export default markdownComponent; 13 | -------------------------------------------------------------------------------- /src/sb/components/markdown/markdown.controller.js: -------------------------------------------------------------------------------- 1 | class MarkdownController { 2 | constructor($rootScope, $parse, $timeout) { 3 | 4 | Object.assign(this, { $rootScope, $parse, $timeout }); 5 | 6 | // Listen for new component data and render it 7 | this.listener = $rootScope.$on('render', (event, entity) => { 8 | $timeout(() => this.render(event, entity.component), 0); 9 | }); 10 | 11 | } 12 | 13 | $onDestroy() { 14 | this.listener(); 15 | } 16 | 17 | render(event, component) { 18 | this.docs = component.docs; 19 | } 20 | 21 | } 22 | 23 | export default MarkdownController; 24 | -------------------------------------------------------------------------------- /src/sb/components/markdown/markdown.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
note_add
4 |
There is no documentation or notes for this component
5 |
-------------------------------------------------------------------------------- /src/sb/components/markdown/markdown.less: -------------------------------------------------------------------------------- 1 | .markdown__message { 2 | 3 | flex-direction: column; 4 | 5 | .material-icons { 6 | font-size: 70px; 7 | } 8 | 9 | } 10 | 11 | @font-face { 12 | font-family: octicons-link; 13 | src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format('woff'); 14 | } 15 | 16 | markdown { 17 | background-color: #fff; 18 | } 19 | 20 | .markdown-body { 21 | -ms-text-size-adjust: 100%; 22 | -webkit-text-size-adjust: 100%; 23 | line-height: 1.5; 24 | color: #24292e; 25 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 26 | font-size: 16px; 27 | line-height: 1.5; 28 | word-wrap: break-word; 29 | padding: 40px; 30 | background-color: #fff; 31 | } 32 | 33 | .markdown-body .pl-c { 34 | color: #6a737d; 35 | } 36 | 37 | .markdown-body .pl-c1, 38 | .markdown-body .pl-s .pl-v { 39 | color: #005cc5; 40 | } 41 | 42 | .markdown-body .pl-e, 43 | .markdown-body .pl-en { 44 | color: #6f42c1; 45 | } 46 | 47 | .markdown-body .pl-smi, 48 | .markdown-body .pl-s .pl-s1 { 49 | color: #24292e; 50 | } 51 | 52 | .markdown-body .pl-ent { 53 | color: #22863a; 54 | } 55 | 56 | .markdown-body .pl-k { 57 | color: #d73a49; 58 | } 59 | 60 | .markdown-body .pl-s, 61 | .markdown-body .pl-pds, 62 | .markdown-body .pl-s .pl-pse .pl-s1, 63 | .markdown-body .pl-sr, 64 | .markdown-body .pl-sr .pl-cce, 65 | .markdown-body .pl-sr .pl-sre, 66 | .markdown-body .pl-sr .pl-sra { 67 | color: #032f62; 68 | } 69 | 70 | .markdown-body .pl-v, 71 | .markdown-body .pl-smw { 72 | color: #e36209; 73 | } 74 | 75 | .markdown-body .pl-bu { 76 | color: #b31d28; 77 | } 78 | 79 | .markdown-body .pl-ii { 80 | color: #fafbfc; 81 | background-color: #b31d28; 82 | } 83 | 84 | .markdown-body .pl-c2 { 85 | color: #fafbfc; 86 | background-color: #d73a49; 87 | } 88 | 89 | .markdown-body .pl-c2::before { 90 | content: "^M"; 91 | } 92 | 93 | .markdown-body .pl-sr .pl-cce { 94 | font-weight: bold; 95 | color: #22863a; 96 | } 97 | 98 | .markdown-body .pl-ml { 99 | color: #735c0f; 100 | } 101 | 102 | .markdown-body .pl-mh, 103 | .markdown-body .pl-mh .pl-en, 104 | .markdown-body .pl-ms { 105 | font-weight: bold; 106 | color: #005cc5; 107 | } 108 | 109 | .markdown-body .pl-mi { 110 | font-style: italic; 111 | color: #24292e; 112 | } 113 | 114 | .markdown-body .pl-mb { 115 | font-weight: bold; 116 | color: #24292e; 117 | } 118 | 119 | .markdown-body .pl-md { 120 | color: #b31d28; 121 | background-color: #ffeef0; 122 | } 123 | 124 | .markdown-body .pl-mi1 { 125 | color: #22863a; 126 | background-color: #f0fff4; 127 | } 128 | 129 | .markdown-body .pl-mc { 130 | color: #e36209; 131 | background-color: #ffebda; 132 | } 133 | 134 | .markdown-body .pl-mi2 { 135 | color: #f6f8fa; 136 | background-color: #005cc5; 137 | } 138 | 139 | .markdown-body .pl-mdr { 140 | font-weight: bold; 141 | color: #6f42c1; 142 | } 143 | 144 | .markdown-body .pl-ba { 145 | color: #586069; 146 | } 147 | 148 | .markdown-body .pl-sg { 149 | color: #959da5; 150 | } 151 | 152 | .markdown-body .pl-corl { 153 | text-decoration: underline; 154 | color: #032f62; 155 | } 156 | 157 | .markdown-body .octicon { 158 | display: inline-block; 159 | vertical-align: text-top; 160 | fill: currentColor; 161 | } 162 | 163 | .markdown-body a { 164 | background-color: transparent; 165 | -webkit-text-decoration-skip: objects; 166 | } 167 | 168 | .markdown-body a:active, 169 | .markdown-body a:hover { 170 | outline-width: 0; 171 | } 172 | 173 | .markdown-body strong { 174 | font-weight: inherit; 175 | } 176 | 177 | .markdown-body strong { 178 | font-weight: bolder; 179 | } 180 | 181 | .markdown-body h1 { 182 | font-size: 2em; 183 | margin: 0.67em 0; 184 | } 185 | 186 | .markdown-body img { 187 | border-style: none; 188 | } 189 | 190 | .markdown-body svg:not(:root) { 191 | overflow: hidden; 192 | } 193 | 194 | .markdown-body code, 195 | .markdown-body kbd, 196 | .markdown-body pre { 197 | font-family: monospace, monospace; 198 | font-size: 1em; 199 | } 200 | 201 | .markdown-body hr { 202 | box-sizing: content-box; 203 | height: 0; 204 | overflow: visible; 205 | } 206 | 207 | .markdown-body input { 208 | font: inherit; 209 | margin: 0; 210 | } 211 | 212 | .markdown-body input { 213 | overflow: visible; 214 | } 215 | 216 | .markdown-body [type="checkbox"] { 217 | box-sizing: border-box; 218 | padding: 0; 219 | } 220 | 221 | .markdown-body * { 222 | box-sizing: border-box; 223 | } 224 | 225 | .markdown-body input { 226 | font-family: inherit; 227 | font-size: inherit; 228 | line-height: inherit; 229 | } 230 | 231 | .markdown-body a { 232 | color: #0366d6; 233 | text-decoration: none; 234 | } 235 | 236 | .markdown-body a:hover { 237 | text-decoration: underline; 238 | } 239 | 240 | .markdown-body strong { 241 | font-weight: 600; 242 | } 243 | 244 | .markdown-body hr { 245 | height: 0; 246 | margin: 15px 0; 247 | overflow: hidden; 248 | background: transparent; 249 | border: 0; 250 | border-bottom: 1px solid #dfe2e5; 251 | } 252 | 253 | .markdown-body hr::before { 254 | display: table; 255 | content: ""; 256 | } 257 | 258 | .markdown-body hr::after { 259 | display: table; 260 | clear: both; 261 | content: ""; 262 | } 263 | 264 | .markdown-body table { 265 | border-spacing: 0; 266 | border-collapse: collapse; 267 | } 268 | 269 | .markdown-body td, 270 | .markdown-body th { 271 | padding: 0; 272 | } 273 | 274 | .markdown-body h1, 275 | .markdown-body h2, 276 | .markdown-body h3, 277 | .markdown-body h4, 278 | .markdown-body h5, 279 | .markdown-body h6 { 280 | margin-top: 0; 281 | margin-bottom: 0; 282 | } 283 | 284 | .markdown-body h1 { 285 | font-size: 32px; 286 | font-weight: 600; 287 | } 288 | 289 | .markdown-body h2 { 290 | font-size: 24px; 291 | font-weight: 600; 292 | } 293 | 294 | .markdown-body h3 { 295 | font-size: 20px; 296 | font-weight: 600; 297 | } 298 | 299 | .markdown-body h4 { 300 | font-size: 16px; 301 | font-weight: 600; 302 | } 303 | 304 | .markdown-body h5 { 305 | font-size: 14px; 306 | font-weight: 600; 307 | } 308 | 309 | .markdown-body h6 { 310 | font-size: 12px; 311 | font-weight: 600; 312 | } 313 | 314 | .markdown-body p { 315 | margin-top: 0; 316 | margin-bottom: 10px; 317 | } 318 | 319 | .markdown-body blockquote { 320 | margin: 0; 321 | } 322 | 323 | .markdown-body ul, 324 | .markdown-body ol { 325 | padding-left: 0; 326 | margin-top: 0; 327 | margin-bottom: 0; 328 | } 329 | 330 | .markdown-body ol ol, 331 | .markdown-body ul ol { 332 | list-style-type: lower-roman; 333 | } 334 | 335 | .markdown-body ul ul ol, 336 | .markdown-body ul ol ol, 337 | .markdown-body ol ul ol, 338 | .markdown-body ol ol ol { 339 | list-style-type: lower-alpha; 340 | } 341 | 342 | .markdown-body dd { 343 | margin-left: 0; 344 | } 345 | 346 | .markdown-body code { 347 | font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 348 | font-size: 12px; 349 | } 350 | 351 | .markdown-body pre { 352 | margin-top: 0; 353 | margin-bottom: 0; 354 | font: 12px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 355 | } 356 | 357 | .markdown-body .octicon { 358 | vertical-align: text-bottom; 359 | } 360 | 361 | .markdown-body .pl-0 { 362 | padding-left: 0 !important; 363 | } 364 | 365 | .markdown-body .pl-1 { 366 | padding-left: 4px !important; 367 | } 368 | 369 | .markdown-body .pl-2 { 370 | padding-left: 8px !important; 371 | } 372 | 373 | .markdown-body .pl-3 { 374 | padding-left: 16px !important; 375 | } 376 | 377 | .markdown-body .pl-4 { 378 | padding-left: 24px !important; 379 | } 380 | 381 | .markdown-body .pl-5 { 382 | padding-left: 32px !important; 383 | } 384 | 385 | .markdown-body .pl-6 { 386 | padding-left: 40px !important; 387 | } 388 | 389 | .markdown-body::before { 390 | display: table; 391 | content: ""; 392 | } 393 | 394 | .markdown-body::after { 395 | display: table; 396 | clear: both; 397 | content: ""; 398 | } 399 | 400 | .markdown-body>*:first-child { 401 | margin-top: 0 !important; 402 | } 403 | 404 | .markdown-body>*:last-child { 405 | margin-bottom: 0 !important; 406 | } 407 | 408 | .markdown-body a:not([href]) { 409 | color: inherit; 410 | text-decoration: none; 411 | } 412 | 413 | .markdown-body .anchor { 414 | float: left; 415 | padding-right: 4px; 416 | margin-left: -20px; 417 | line-height: 1; 418 | } 419 | 420 | .markdown-body .anchor:focus { 421 | outline: none; 422 | } 423 | 424 | .markdown-body p, 425 | .markdown-body blockquote, 426 | .markdown-body ul, 427 | .markdown-body ol, 428 | .markdown-body dl, 429 | .markdown-body table, 430 | .markdown-body pre { 431 | margin-top: 0; 432 | margin-bottom: 16px; 433 | } 434 | 435 | .markdown-body hr { 436 | height: 0.25em; 437 | padding: 0; 438 | margin: 24px 0; 439 | background-color: #e1e4e8; 440 | border: 0; 441 | } 442 | 443 | .markdown-body blockquote { 444 | padding: 0 1em; 445 | color: #6a737d; 446 | border-left: 0.25em solid #dfe2e5; 447 | } 448 | 449 | .markdown-body blockquote>:first-child { 450 | margin-top: 0; 451 | } 452 | 453 | .markdown-body blockquote>:last-child { 454 | margin-bottom: 0; 455 | } 456 | 457 | .markdown-body kbd { 458 | display: inline-block; 459 | padding: 3px 5px; 460 | font-size: 11px; 461 | line-height: 10px; 462 | color: #444d56; 463 | vertical-align: middle; 464 | background-color: #fafbfc; 465 | border: solid 1px #c6cbd1; 466 | border-bottom-color: #959da5; 467 | border-radius: 3px; 468 | box-shadow: inset 0 -1px 0 #959da5; 469 | } 470 | 471 | .markdown-body h1, 472 | .markdown-body h2, 473 | .markdown-body h3, 474 | .markdown-body h4, 475 | .markdown-body h5, 476 | .markdown-body h6 { 477 | margin-top: 24px; 478 | margin-bottom: 16px; 479 | font-weight: 600; 480 | line-height: 1.25; 481 | } 482 | 483 | .markdown-body h1 .octicon-link, 484 | .markdown-body h2 .octicon-link, 485 | .markdown-body h3 .octicon-link, 486 | .markdown-body h4 .octicon-link, 487 | .markdown-body h5 .octicon-link, 488 | .markdown-body h6 .octicon-link { 489 | color: #1b1f23; 490 | vertical-align: middle; 491 | visibility: hidden; 492 | } 493 | 494 | .markdown-body h1:hover .anchor, 495 | .markdown-body h2:hover .anchor, 496 | .markdown-body h3:hover .anchor, 497 | .markdown-body h4:hover .anchor, 498 | .markdown-body h5:hover .anchor, 499 | .markdown-body h6:hover .anchor { 500 | text-decoration: none; 501 | } 502 | 503 | .markdown-body h1:hover .anchor .octicon-link, 504 | .markdown-body h2:hover .anchor .octicon-link, 505 | .markdown-body h3:hover .anchor .octicon-link, 506 | .markdown-body h4:hover .anchor .octicon-link, 507 | .markdown-body h5:hover .anchor .octicon-link, 508 | .markdown-body h6:hover .anchor .octicon-link { 509 | visibility: visible; 510 | } 511 | 512 | .markdown-body h1 { 513 | padding-bottom: 0.3em; 514 | font-size: 2em; 515 | border-bottom: 1px solid #eaecef; 516 | } 517 | 518 | .markdown-body h2 { 519 | padding-bottom: 0.3em; 520 | font-size: 1.5em; 521 | border-bottom: 1px solid #eaecef; 522 | } 523 | 524 | .markdown-body h3 { 525 | font-size: 1.25em; 526 | } 527 | 528 | .markdown-body h4 { 529 | font-size: 1em; 530 | } 531 | 532 | .markdown-body h5 { 533 | font-size: 0.875em; 534 | } 535 | 536 | .markdown-body h6 { 537 | font-size: 0.85em; 538 | color: #6a737d; 539 | } 540 | 541 | .markdown-body ul, 542 | .markdown-body ol { 543 | padding-left: 2em; 544 | } 545 | 546 | .markdown-body ul ul, 547 | .markdown-body ul ol, 548 | .markdown-body ol ol, 549 | .markdown-body ol ul { 550 | margin-top: 0; 551 | margin-bottom: 0; 552 | } 553 | 554 | .markdown-body li>p { 555 | margin-top: 16px; 556 | } 557 | 558 | .markdown-body li+li { 559 | margin-top: 0.25em; 560 | } 561 | 562 | .markdown-body dl { 563 | padding: 0; 564 | } 565 | 566 | .markdown-body dl dt { 567 | padding: 0; 568 | margin-top: 16px; 569 | font-size: 1em; 570 | font-style: italic; 571 | font-weight: 600; 572 | } 573 | 574 | .markdown-body dl dd { 575 | padding: 0 16px; 576 | margin-bottom: 16px; 577 | } 578 | 579 | .markdown-body table { 580 | display: block; 581 | width: 100%; 582 | overflow: auto; 583 | } 584 | 585 | .markdown-body table th { 586 | font-weight: 600; 587 | } 588 | 589 | .markdown-body table th, 590 | .markdown-body table td { 591 | padding: 6px 13px; 592 | border: 1px solid #dfe2e5; 593 | } 594 | 595 | .markdown-body table tr { 596 | background-color: #fff; 597 | border-top: 1px solid #c6cbd1; 598 | } 599 | 600 | .markdown-body table tr:nth-child(2n) { 601 | background-color: #f6f8fa; 602 | } 603 | 604 | .markdown-body img { 605 | max-width: 100%; 606 | box-sizing: content-box; 607 | background-color: #fff; 608 | } 609 | 610 | .markdown-body code { 611 | padding: 0; 612 | padding-top: 0.2em; 613 | padding-bottom: 0.2em; 614 | margin: 0; 615 | font-size: 85%; 616 | background-color: rgba(27,31,35,0.05); 617 | border-radius: 3px; 618 | } 619 | 620 | .markdown-body code::before, 621 | .markdown-body code::after { 622 | letter-spacing: -0.2em; 623 | content: "\00a0"; 624 | } 625 | 626 | .markdown-body pre { 627 | word-wrap: normal; 628 | } 629 | 630 | .markdown-body pre>code { 631 | padding: 0; 632 | margin: 0; 633 | font-size: 100%; 634 | word-break: normal; 635 | white-space: pre; 636 | background: transparent; 637 | border: 0; 638 | } 639 | 640 | .markdown-body .highlight { 641 | margin-bottom: 16px; 642 | } 643 | 644 | .markdown-body .highlight pre { 645 | margin-bottom: 0; 646 | word-break: normal; 647 | } 648 | 649 | .markdown-body .highlight pre, 650 | .markdown-body pre { 651 | padding: 16px; 652 | overflow: auto; 653 | font-size: 85%; 654 | line-height: 1.45; 655 | background-color: #f6f8fa; 656 | border-radius: 3px; 657 | } 658 | 659 | .markdown-body pre code { 660 | display: inline; 661 | max-width: auto; 662 | padding: 0; 663 | margin: 0; 664 | overflow: visible; 665 | line-height: inherit; 666 | word-wrap: normal; 667 | background-color: transparent; 668 | border: 0; 669 | } 670 | 671 | .markdown-body pre code::before, 672 | .markdown-body pre code::after { 673 | content: normal; 674 | } 675 | 676 | .markdown-body .full-commit .btn-outline:not(:disabled):hover { 677 | color: #005cc5; 678 | border-color: #005cc5; 679 | } 680 | 681 | .markdown-body kbd { 682 | display: inline-block; 683 | padding: 3px 5px; 684 | font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; 685 | line-height: 10px; 686 | color: #444d56; 687 | vertical-align: middle; 688 | background-color: #fafbfc; 689 | border: solid 1px #d1d5da; 690 | border-bottom-color: #c6cbd1; 691 | border-radius: 3px; 692 | box-shadow: inset 0 -1px 0 #c6cbd1; 693 | } 694 | 695 | .markdown-body :checked+.radio-label { 696 | position: relative; 697 | z-index: 1; 698 | border-color: #0366d6; 699 | } 700 | 701 | .markdown-body .task-list-item { 702 | list-style-type: none; 703 | } 704 | 705 | .markdown-body .task-list-item+.task-list-item { 706 | margin-top: 3px; 707 | } 708 | 709 | .markdown-body .task-list-item input { 710 | margin: 0 0.2em 0.25em -1.6em; 711 | vertical-align: middle; 712 | } 713 | 714 | .markdown-body hr { 715 | border-bottom-color: #eee; 716 | } -------------------------------------------------------------------------------- /src/sb/components/model/model.component.js: -------------------------------------------------------------------------------- 1 | import template from './model.html'; 2 | import controller from './model.controller'; 3 | import './model.less'; 4 | 5 | let modelComponent = { 6 | bindings: {}, 7 | controllerAs: 'vm', 8 | template, 9 | controller 10 | }; 11 | 12 | export default modelComponent; 13 | -------------------------------------------------------------------------------- /src/sb/components/model/model.controller.js: -------------------------------------------------------------------------------- 1 | class ModelController { 2 | constructor($rootScope, $parse) { 3 | this.$parse = $parse; 4 | 5 | if (window.sbtype === 'react') { 6 | this.renderError = true; 7 | this.errorMessage = 'Sorry but for now SB not support live component editor for React. We work on this. Stay tuned!'; 8 | } else { 9 | 10 | // Listen for new component data and render it 11 | this.listener = $rootScope.$on('render', (event, entity) => { 12 | setTimeout(() => { 13 | this.render(event, entity.component) 14 | $rootScope.$apply(); 15 | }, 0); 16 | }); 17 | 18 | // ACE editor settings 19 | this.settings = { 20 | mode: 'json', 21 | useWrapMode: true, 22 | onLoad: this.onEditorChange.bind(this) 23 | } 24 | this.$rootScope = $rootScope; 25 | this.inFirst = true; 26 | 27 | } 28 | 29 | } 30 | 31 | $onDestroy() { 32 | this.listener(); 33 | } 34 | 35 | onEditorChange(editor) { 36 | editor.$blockScrolling = Infinity; 37 | let session = editor.getSession(); 38 | 39 | // On editor change try to load new component 40 | session.on("change", (e) => { 41 | this.broadcastModel(session.getValue()); 42 | }); 43 | } 44 | 45 | broadcastModel(model) { 46 | 47 | // Prevent first paint canges 48 | if (this.inFirst) { 49 | this.inFirst = false; 50 | return; 51 | } 52 | 53 | // Try to render new molel 54 | try { 55 | let v = JSON.parse(model); 56 | this.component.model = v; 57 | this.$rootScope.$broadcast('updateComponent', this.component); 58 | } catch (e) { } 59 | } 60 | 61 | render(event, component) { 62 | 63 | // We need original template for prevent changes 64 | // So store original component 65 | this.originalComponent = component; 66 | this.component = component; 67 | 68 | try { 69 | // Store model 70 | this.model = JSON.stringify(component.model, null, Number(4)); 71 | this.renderError = false; 72 | } catch (e) { 73 | this.renderError = true; 74 | } 75 | 76 | } 77 | 78 | } 79 | 80 | export default ModelController; 81 | -------------------------------------------------------------------------------- /src/sb/components/model/model.html: -------------------------------------------------------------------------------- 1 |
2 |
-------------------------------------------------------------------------------- /src/sb/components/model/model.less: -------------------------------------------------------------------------------- 1 | model { 2 | background: #fff; 3 | font-size: 14px; 4 | 5 | .ace_editor { 6 | font-size: 14px; 7 | } 8 | 9 | .ace_print-margin { 10 | display: none !important; 11 | } 12 | 13 | } 14 | 15 | .ace-tm { 16 | 17 | .ace_gutter-active-line, .ace_active-line { 18 | background-color: #f0f0f0; 19 | } 20 | 21 | .ace_gutter { 22 | background: #fff; 23 | color: rgba(0, 0, 0, 0.54); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/sb/components/preview/devices.js: -------------------------------------------------------------------------------- 1 | export let devicesSize = { 2 | Custom: { 3 | width: 600, 4 | height: 450 5 | }, 6 | 'iPhone 5': { 7 | width: 320, 8 | height: 568 9 | }, 10 | 'iPhone 6': { 11 | width: 375, 12 | height: 667 13 | }, 14 | 'iPhone 6 Plus': { 15 | width: 414, 16 | height: 736 17 | }, 18 | 'iPad': { 19 | width: 768, 20 | height: 1024 21 | }, 22 | 'Nexus 5X': { 23 | width: 412, 24 | height: 732 25 | }, 26 | 'Nexus 6P': { 27 | width: 412, 28 | height: 732 29 | } 30 | }; 31 | 32 | 33 | export let devices = ['Custom', 'iPhone 5', 'iPhone 6', 'iPhone 6 Plus', 'iPad', 'Nexus 5X', 'Nexus 6P']; -------------------------------------------------------------------------------- /src/sb/components/preview/preview.component.js: -------------------------------------------------------------------------------- 1 | import template from './preview.html'; 2 | import controller from './preview.controller'; 3 | import './preview.less'; 4 | 5 | let previewComponent = { 6 | bindings: {}, 7 | controllerAs: 'vm', 8 | template, 9 | controller 10 | }; 11 | 12 | export default previewComponent; 13 | -------------------------------------------------------------------------------- /src/sb/components/preview/preview.controller.js: -------------------------------------------------------------------------------- 1 | import { 2 | devicesSize, 3 | devices 4 | } from './devices'; 5 | 6 | class PreviewController { 7 | 8 | constructor($rootScope, $scope, $state, $stateParams) { 9 | 10 | this.$state = $state; 11 | this.$stateParams = $stateParams; 12 | 13 | this.listener = $rootScope.$on('render', (event, entity) => { 14 | this.setDocumentTitle(entity.sbObject.point); 15 | this.render(event, { 16 | type: 'component', 17 | data: entity.sbObject 18 | }); 19 | }); 20 | 21 | this.templateListener = $rootScope.$on('updateComponent', (event, component) => { 22 | this.updateSBComponent(component); 23 | }); 24 | 25 | this.devices = devices; 26 | 27 | this.devicesSize = devicesSize; 28 | 29 | this.initDevice(); 30 | 31 | $rootScope.$on('angular-resizable.resizeEnd', (event, args) => { 32 | if (args.width) { 33 | this.dynamicSize.width = args.width; 34 | } 35 | if (args.height) { 36 | this.dynamicSize.height = args.height; 37 | } 38 | this.selectedDevice = this.devices[0]; 39 | }); 40 | 41 | } 42 | 43 | $postLink() { 44 | this._bridge = window.frames.preview; 45 | } 46 | 47 | $onDestroy() { 48 | this.listener(); 49 | } 50 | 51 | render(event, data) { 52 | try { 53 | this._bridge.postMessage(data, '*'); 54 | } catch (e) { 55 | console.log(e); 56 | } 57 | } 58 | 59 | initDevice() { 60 | let device = this.$state.params.device; 61 | if (device) { 62 | this.selectedDevice = device; 63 | this.dynamicSize = this.devicesSize[device]; 64 | } else { 65 | this.dynamicSize = { 66 | width: 600, 67 | height: 450 68 | } 69 | this.selectedDevice = this.devices[0]; 70 | } 71 | } 72 | 73 | updateSBComponent(component, type) { 74 | let params = { 75 | section: this.$stateParams.section, 76 | story: this.$stateParams.story, 77 | id: component.id 78 | }; 79 | window.sb.updateStory(params, component); 80 | this.render(event, { 81 | type: 'component', 82 | data: params 83 | }); 84 | } 85 | 86 | selectDevice(device) { 87 | let params = this.$state.params; 88 | params.device = device; 89 | this.$state.go('main.storybook', params, { 90 | reload: false, 91 | location: true, 92 | inherit: false, 93 | notify: false 94 | }); 95 | this.dynamicSize = this.devicesSize[device]; 96 | } 97 | 98 | setDocumentTitle(title) { 99 | document.title = `${title} — SB`; 100 | } 101 | 102 | } 103 | 104 | export default PreviewController; 105 | -------------------------------------------------------------------------------- /src/sb/components/preview/preview.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
19 | 20 |
21 |
-------------------------------------------------------------------------------- /src/sb/components/preview/preview.less: -------------------------------------------------------------------------------- 1 | .preview__wrapper { 2 | 3 | // padding: 0 30px; 4 | width: 100%; 5 | height: 100%; 6 | 7 | md-input-container { 8 | margin: 0 !important; 9 | max-width: 120px; 10 | } 11 | 12 | .preview__heder { 13 | display: none; 14 | background: #fff; 15 | margin: 0 -30px; 16 | padding: 5px; 17 | box-shadow: 0px 1px 1px rgba(184,184,184,0.54); 18 | justify-content: center; 19 | 20 | input { 21 | width: 40px; 22 | text-align: center; 23 | } 24 | 25 | } 26 | 27 | .resizable { 28 | width: 100%; 29 | height: 100%; 30 | } 31 | 32 | .rg-bottom { 33 | display: none; 34 | padding: 5px 0; 35 | } 36 | 37 | .rg-right { 38 | display: none; 39 | padding: 0 5px; 40 | } 41 | 42 | iframe { 43 | width: 100%; 44 | height: 100%; 45 | } 46 | 47 | } 48 | 49 | .responsive__active { 50 | 51 | .preview__heder { 52 | display: flex; 53 | } 54 | 55 | .resizable { 56 | position: relative; 57 | margin: 25px auto; 58 | background: #fff; 59 | box-shadow: 0px 1px 2px rgba(184, 184, 184, 0.54); 60 | border-radius: 2px; 61 | } 62 | 63 | .rg-bottom { 64 | display: block; 65 | margin-bottom: -25px; 66 | 67 | &:hover { 68 | background: rgba(0, 0, 0, 0.04); 69 | } 70 | 71 | } 72 | 73 | .rg-right { 74 | display: block; 75 | margin-right: -25px; 76 | 77 | &:hover { 78 | background: rgba(0, 0, 0, 0.04); 79 | } 80 | 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /src/sb/components/storyList/storyList.component.js: -------------------------------------------------------------------------------- 1 | import template from './storyList.html'; 2 | import controller from './storyList.controller'; 3 | import './storyList.less'; 4 | 5 | let storyListComponent = { 6 | bindings: {}, 7 | controllerAs: 'vm', 8 | template, 9 | controller 10 | }; 11 | 12 | export default storyListComponent; 13 | -------------------------------------------------------------------------------- /src/sb/components/storyList/storyList.controller.js: -------------------------------------------------------------------------------- 1 | class StoryListController { 2 | 3 | constructor($rootScope, $window, $state, $mdSidenav, $scope) { 4 | "ngInject"; 5 | 6 | this.$mdSidenav = $mdSidenav; 7 | this.$rootScope = $rootScope; 8 | this.$window = $window; 9 | this.$state = $state; 10 | this.$scope = $scope; 11 | 12 | sb.registerContactCB(() => { 13 | this.selectComponent(); 14 | this.$scope.$apply(); 15 | }); 16 | 17 | sb.registerReloadCB(() => { 18 | this.initStories(); 19 | this.$scope.$apply(); 20 | }); 21 | 22 | this.initStories(); 23 | 24 | this.$mdSidenav('left').open(); 25 | 26 | } 27 | 28 | initStories() { 29 | // Get all section 30 | this.sections = sb.getSections(); 31 | 32 | // List of avaliable sections 33 | this.sectionsList = Object.keys(this.sections); 34 | 35 | // Active stories 36 | this.stories = {}; 37 | 38 | // Active story point 39 | this.active = this.active ? this.active : {}; 40 | 41 | this.selectStory(); 42 | } 43 | 44 | openSearch() { 45 | this.searchPanel = true; 46 | setTimeout(() => document.getElementsByClassName('search__input')[0].focus(), 0); 47 | } 48 | 49 | closeSearch() { 50 | this.search = ''; 51 | this.searchPanel = false; 52 | } 53 | 54 | selectSection(sectionTitle) { 55 | this.selectStory(sectionTitle) 56 | this.selectComponent(true); 57 | } 58 | 59 | selectStory(sectionTitle) { 60 | const section = sectionTitle || this.$state.params.section; 61 | if (section && this.sections[section]) { 62 | this.selectedSection = section; 63 | this.stories = this.sections[section]; 64 | } else { 65 | this.selectedSection = this.sectionsList[0]; 66 | this.stories = this.sections[this.selectedSection]; 67 | } 68 | } 69 | 70 | selectComponentFromList(story, component) { 71 | let params = this.$state.params; 72 | this.active = { story, point: component.title, section: this.selectedSection }; 73 | 74 | params.story = story; 75 | params.point = component.title; 76 | params.section = this.selectedSection; 77 | 78 | this.$state.go('main.storybook', params, { 79 | reload: false, 80 | location: true, 81 | inherit: false, 82 | notify: false 83 | }); 84 | 85 | this.closeSearch(); 86 | 87 | this.$rootScope.$broadcast('render', { 88 | component, 89 | sbObject: { 90 | id: component.id, 91 | story, 92 | point: component.title, 93 | section: this.selectedSection 94 | } 95 | }); 96 | } 97 | 98 | selectComponent(force) { 99 | let section, storyTitle, pointTitle, component; 100 | let params = this.$state.params; 101 | 102 | if (!force && this.$state.params.story && this.$state.params.point) { 103 | section = this.$state.params.section; 104 | storyTitle = this.$state.params.story; 105 | pointTitle = this.$state.params.point; 106 | if (this.sections[section] && this.sections[section][storyTitle]) { 107 | component = this.sections[section][storyTitle].find(point => point.title === pointTitle); 108 | } 109 | } 110 | 111 | if (!component) { 112 | storyTitle = Object.keys(this.stories)[0]; 113 | component = this.stories[storyTitle][0]; 114 | } 115 | 116 | this.active = { story: storyTitle, point: pointTitle, section: this.selectedSection }; 117 | 118 | params.story = storyTitle; 119 | params.point = component.title; 120 | params.section = this.selectedSection; 121 | 122 | this.$state.go('main.storybook', params, { 123 | reload: false, 124 | location: true, 125 | inherit: false, 126 | notify: false 127 | }); 128 | 129 | this.$rootScope.$broadcast('render', { 130 | component, 131 | sbObject: { 132 | id: component.id, 133 | story: storyTitle, 134 | point: component.title, 135 | section: this.selectedSection 136 | } 137 | }); 138 | 139 | } 140 | 141 | sloseSidebar() { 142 | this.$mdSidenav('left').close(); 143 | } 144 | 145 | } 146 | 147 | export default StoryListController; 148 | -------------------------------------------------------------------------------- /src/sb/components/storyList/storyList.html: -------------------------------------------------------------------------------- 1 | 23 | 24 |

Section

25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 |
33 | 34 | 36 |
37 |

38 |
39 |
40 |
41 |
-------------------------------------------------------------------------------- /src/sb/components/storyList/storyList.less: -------------------------------------------------------------------------------- 1 | story-list { 2 | overflow: hidden; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | .sidebar__header { 8 | align-items: center; 9 | justify-content: space-between; 10 | border-bottom: 1px solid rgba(0,0,0,0.12); 11 | } 12 | 13 | .sidebar__header-main { 14 | display: flex; 15 | align-items: center; 16 | width: 100%; 17 | } 18 | 19 | .icon__search { 20 | color: rgba(0, 0, 0, 0.54); 21 | } 22 | 23 | .search { 24 | 25 | display: flex; 26 | align-items: center; 27 | padding-left: 13px; 28 | 29 | .search__input { 30 | width: 210px; 31 | height: 60px; 32 | border: none; 33 | padding: 0 10px; 34 | outline: none; 35 | } 36 | 37 | } 38 | 39 | .story__name { 40 | font-size: 14px; 41 | font-weight: 500; 42 | color: #448aff; 43 | letter-spacing: 0px; 44 | padding: 16px; 45 | background: #fff; 46 | } 47 | 48 | .story__point { 49 | cursor: pointer; 50 | color: rgba(0,0,0,0.54); 51 | outline: none; 52 | height: 48px !important; 53 | min-height: 48px !important; 54 | 55 | .md-button { 56 | padding-left: 32px !important; 57 | min-height: 48px !important; 58 | height: 48px !important; 59 | } 60 | 61 | &.active { 62 | color: rgb(68,138,255); 63 | } 64 | 65 | } 66 | 67 | .story__list { 68 | overflow: scroll; 69 | 70 | .story__list-item { 71 | font-size: 14px !important; 72 | } 73 | 74 | } 75 | 76 | .button__close-sidebar { 77 | margin-right: 16px; 78 | color: rgba(0,0,0,0.54); 79 | } 80 | 81 | .section__select { 82 | 83 | padding: 0 16px; 84 | 85 | h2 { 86 | font-size: 16px; 87 | font-weight: 500; 88 | color: rgba(0, 0, 0, 0.54); 89 | margin: 8px 0; 90 | } 91 | 92 | md-select { 93 | display: inline-block; 94 | } 95 | 96 | span { 97 | color: rgba(0, 0, 0, 0.54); 98 | text-transform: capitalize; 99 | } 100 | 101 | } 102 | 103 | .md-subheader-wrapper:not(.md-sticky-no-effect)[sticky-state=active] { 104 | box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 3px; 105 | } 106 | 107 | .sb-logo { 108 | width: 65px; 109 | height: 60px; 110 | background-size: 40px; 111 | background-repeat: no-repeat; 112 | background-position: 50%; 113 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAMAAABHPGVmAAACnVBMVEUDm+UEnOYFnOYGneYHneYIneYJnuYKnuYLn+YMn+YNn+cOoOcPoOcQoecRoecSoecToucUoucVo+cWo+cXo+gYpOgZpOgapegbpegcpegdpugepuggp+ghp+kiqOkjqOkkqOklqekmqeknqukoqukpqukqq+krq+osrOotrOourOovreoyruozruo0r+o1r+s2r+s3sOs4sOs5ses6ses7ses8sus+s+w/s+xAs+xBtOxCtOxEtexGtuxHtuxIt+1Jt+1Kt+1MuO1Nue1Oue1Pue1Quu1Ruu1Suu5Uu+5WvO5XvO5Xve5Yve5Zvu5avu5bvu9cv+9ewO9fwO9gwO9hwe9iwe9jwu9kwu9lwvBmw/Bnw/Bow/BpxPBqxPBrxfBuxvFwx/Fxx/Fyx/FzyPF1yfF2yfF3yfF4yvJ5yvJ6y/J7y/J8y/J9zPJ+zPJ/zfKAzfKBzfKCzvODzvOEzvOFz/OGz/OI0POJ0POK0fOL0fOM0vSO0vSP0/SR1PSS1PST1PSU1fSV1fSW1vWY1vWZ1/Wa1/Wb1/Wc2PWd2PWe2fWf2fag2fah2vaj2/ak2/al2/am3Pao3fap3feq3fer3vet3/eu3/ev4Pew4Pex4fey4fiz4fi04vi24vi34/i44/i55Pi65Pi75Pi85fm95fm+5vm/5vnA5vnB5/nC5/nD6PnE6PnF6PnG6frJ6vrK6vrM6/rN6/rO7PrP7PvQ7fvR7fvS7fvT7vvU7vvV7/vW7/vX7/vY8Pva8fzb8fzc8fzd8vze8vzf8/zh8/zi9Pzj9P3k9f3m9f3n9v3o9v3q9/3r9/3s+P3t+P7v+f7w+f7x+v7y+v7z+v70+/71+/73/P/4/P/5/f/6/f/7/v/8/v/9/v/+//////8nARywAAAE1ElEQVR4Ae3Z61dU1R/H8c8wDiKC/lR+ipoppqlYiRch08C8ZKkkRhcz0ygsxbxTVpRalmXe07xUlJfIMivDyAItQbwooWIiiPr5W9LFzP7uc86eOeeJPTqvh6zFem9Y+5z5rDXgf8CP+BE/4s6P+BE/4kfqdxaMG57WIb7boFFTV1feicjZhYMD0KUWnKZJS940gycLlq/ZcS525HBeCA6hGabMH4huwJwDUSOXnoZZp510+BQxZXx2wxgp7YGoXqJdEVwMrzZEShBLIW0mwE3SZhVxaShv0aoX3H1ii7wHF6HfqWuAB8HdlsjxtnAzlLpD8CL5vB7JgruvqPkAnjyrRT6GRcIDUxe8WZTbGxZjqJkNT+IqJTIEmpRl9Wz1Uw40gfMUWVCy5olnMjvBYqGKVELz4lWKRdBspuho+7HYngrNQBWZDzGXFvkIaze9jKIWooJWDQ9BczYSGQVlwHVaXOuH20asbaCuFEqwmTY1iRCHI5E+UFbRpgRIfaWKNiu0Y9FhGcTuSCQeyve0qZv85XU6TIMylQ7fQmwNR+ohjtCTdCjFdKiD2BuONEHsphfX2sT8jZtxUMrBVkn6I+rFbxDVMf+S+MZIpC+UUBU92AIl8SYdSqGMJuRhUNLO0N08KMMY81q8Q8jBRNc9dDUOygw6HAwgokODivzdFrrJx+miJ5SVtPulC5RFVBHOgUXclO8Yy0WIMlpdWZoAZVCTFqkNwebeN04yqoMQfzYoF2vL1z+VBJFcQS3Ct+GUtaGJZu/Dk6QfaYkwGwYpr9XTZBa8SD9KW+TiUJh0LGmmUybcJS9pcu6uSyNh1K+cDslwM3DFBeNMvVYYgEn8u7Q5CTfpFKBF2QgYFdDqC7gaVWWPiL2ZMHmeFq/DXWixIyL2PxyA00fU5cKL2c6IOPFqCuwSqqgZCE8KDBHRvCkDNrkUzUEomeNEztAusCgxRsTXw2ARrKHyK8QZWlQWJEAknDBHxLrO0C2jsgnK/2hXcRfEc24Rnro/yhCeC+VBOhxNhNL+H7cIL6dDtGthxFj9BjktgNjnGmFVEKKWEd2hrKFTLUSxJdKyjwZ5pkF2AcYpKHpBeUGL1BR1jb9Bp20Q3zDsAMQFGoyEkhuJXN/1SMA8n3jEdOjVULrTJANKfmvk1OIe9jeHqIT4i2EzoeTQpBuUBSRROlENyvF02g/RyLDhUAppUAnrxcA9UOKO0WERlGRGtIeyngYvQ3xOEjMgHqddUy/DY1cNcZhOR9pACZ4jiY3QfBjjTLLhdkEJNNLheE+IsbwFNdDEb7X/s0TgNMOWQ0mjw8bO0GzhLbDtjrmXqRzLgWYEI6ZAmUSr6lWDoevQ2BrZAYuuSyt42+ltE4LQ7WREfyh3j9dkZ6TAZi1vA2/0gU1iWkb/zrDJZsTVOHg1Rn0yrocHIbne5fCqfY2KcCLcFVPZ6LlxgBKp+7+H3SEK4U3yIWoRliUgtiduUmTDk54/28ZdWSJimdlie/u5C8y+7JipP3RCVF12UVcHD+47REVFeO4xRPHoWVqUwU3b6SohkVbb+8EplH+UNisRU9/8tfW0AcW+SUHo2mQuOUOHDdPM8mYVlawrraMBqLtSVjxhSO/kUOrg0ZPn77nif0njR/yIH/EjfsSP3An/AnDC+zGNmyzjAAAAAElFTkSuQmCC); 114 | } -------------------------------------------------------------------------------- /src/sb/components/template/template.component.js: -------------------------------------------------------------------------------- 1 | import template from './template.partial.html'; 2 | import controller from './template.controller'; 3 | import './template.less'; 4 | 5 | let templateComponent = { 6 | bindings: {}, 7 | controllerAs: 'vm', 8 | template, 9 | controller 10 | }; 11 | 12 | export default templateComponent; 13 | -------------------------------------------------------------------------------- /src/sb/components/template/template.controller.js: -------------------------------------------------------------------------------- 1 | class TemplateController { 2 | constructor($rootScope) { 3 | 4 | this.$rootScope = $rootScope; 5 | 6 | if (window.sbtype === 'react') { 7 | this.renderError = true; 8 | this.errorMessage = 'Sorry but for now SB not support live component editor for React. We work on this. Stay tuned!'; 9 | } else { 10 | 11 | // Listen for new component data and render it 12 | this.listener = $rootScope.$on('render', (event, entity) => { 13 | this.render(event, entity.component); 14 | }); 15 | 16 | // ACE editor settings 17 | this.settings = { 18 | mode: 'html', 19 | useWrapMode: true, 20 | onLoad: this.onEditorChange.bind(this) 21 | } 22 | 23 | this.errorMessage = 'Unable to load template. Are you pass it with string?'; 24 | 25 | } 26 | 27 | } 28 | 29 | $onDestroy() { 30 | this.listener(); 31 | } 32 | 33 | onEditorChange(editor) { 34 | editor.$blockScrolling = Infinity; 35 | let session = editor.getSession(); 36 | 37 | // On editor change try to load new component 38 | session.on("change", (e) => { 39 | this.broadcastModel(session.getValue()); 40 | }); 41 | } 42 | 43 | broadcastModel(template) { 44 | 45 | // Prevent first paint canges 46 | if (this.inFirst) { 47 | this.inFirst = false; 48 | return; 49 | } 50 | 51 | // Update component template 52 | this.component.template = template; 53 | 54 | // Try to render new template 55 | try { 56 | this.$rootScope.$broadcast('updateComponent', this.component); 57 | } catch (e) { 58 | console.log(`Can't render template: ${e}`) 59 | } 60 | } 61 | 62 | render(event, component) { 63 | 64 | if (typeof component.template !== 'string') { 65 | this.renderError = true; 66 | return; 67 | } 68 | 69 | this.renderError = false; 70 | 71 | this.component = component; 72 | } 73 | 74 | } 75 | 76 | export default TemplateController; 77 | -------------------------------------------------------------------------------- /src/sb/components/template/template.less: -------------------------------------------------------------------------------- 1 | view { 2 | background: #fff; 3 | font-size: 14px; 4 | 5 | .ace_editor { 6 | font-size: 14px; 7 | } 8 | 9 | } 10 | 11 | .ace-tm { 12 | 13 | .ace_print-margin { 14 | display: none; 15 | } 16 | 17 | .ace_gutter-active-line, .ace_active-line { 18 | background-color: #f0f0f0; 19 | } 20 | 21 | .ace_gutter { 22 | background: #fff; 23 | color: rgba(0, 0, 0, 0.54); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/sb/components/template/template.partial.html: -------------------------------------------------------------------------------- 1 |
2 |
-------------------------------------------------------------------------------- /src/sb/core/core.module.js: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import 'angular-ui-router'; 4 | import 'angular-sanitize'; 5 | 6 | import 'angular-material'; 7 | import 'angular-animate'; 8 | import 'angular-material/angular-material.css'; 9 | 10 | import 'angular-resizable'; 11 | import 'angular-resizable/angular-resizable.min.css'; 12 | 13 | import 'ace-builds/src-min-noconflict/ace.js'; 14 | import 'ace-builds/src-min-noconflict/mode-json.js'; 15 | import 'ace-builds/src-min-noconflict/mode-html.js'; 16 | import 'angular-ui-ace'; 17 | 18 | import 'jsonformatter'; 19 | 20 | import routeConfig from './core.route'; 21 | 22 | const core = angular.module('sb.core', [ 23 | 'ui.router', 24 | 'ngSanitize', 25 | 'ngMaterial', 26 | 'ngAnimate', 27 | 'angularResizable', 28 | 'ui.ace', 29 | 'jsonFormatter' 30 | ]); 31 | 32 | core.constant('local', (() => { 33 | let isLocal = document.location.hostname === 'localhost'; 34 | return isLocal; 35 | })()); 36 | 37 | // Module run fucntion 38 | core.run(runFunc); 39 | 40 | // Router config 41 | core.config(routeConfig); 42 | 43 | // Thema config 44 | core.config(($mdThemingProvider) => { 45 | $mdThemingProvider.theme('default') 46 | .accentPalette('blue'); 47 | }); 48 | 49 | function runFunc() { 50 | } 51 | 52 | export default core; -------------------------------------------------------------------------------- /src/sb/core/core.route.js: -------------------------------------------------------------------------------- 1 | export default function routerConfiguration($urlRouterProvider, $stateProvider, $httpProvider, $locationProvider) { 2 | "ngInject"; 3 | 4 | $httpProvider.defaults.cache = true; 5 | $stateProvider 6 | .state('main', { 7 | abstract: true, 8 | views: { 9 | '': { 10 | template: `` 11 | } 12 | } 13 | }) 14 | 15 | $urlRouterProvider.otherwise('/'); 16 | } -------------------------------------------------------------------------------- /src/sb/directives/directives.module.js: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | const directives = angular.module('sb.directives', []); 4 | 5 | export default directives; -------------------------------------------------------------------------------- /src/sb/index.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | 3 | import './styles/app.less' 4 | 5 | import './app.module'; 6 | 7 | let element = document.getElementById('asb__main'); 8 | 9 | angular 10 | .element(element) 11 | .ready(() => { 12 | angular.bootstrap(element, ['sb'], { strictDi: false }); 13 | }); -------------------------------------------------------------------------------- /src/sb/modules/modules.module.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | 3 | import storybook from './storybook/storybook'; 4 | 5 | let module = angular.module('sb.modules', [ 6 | storybook 7 | ]).name; 8 | 9 | export default module; -------------------------------------------------------------------------------- /src/sb/modules/storybook/helper.compile.js: -------------------------------------------------------------------------------- 1 | export default $compile => (scope, element, attrs) => { 2 | scope.$watch( 3 | scope => scope.$eval(attrs.compile), 4 | value => { 5 | element.html(value); 6 | $compile(element.contents())(scope); 7 | } 8 | ); 9 | }; -------------------------------------------------------------------------------- /src/sb/modules/storybook/storybook.component.js: -------------------------------------------------------------------------------- 1 | import template from './storybook.html'; 2 | import controller from './storybook.controller'; 3 | import './storybook.less'; 4 | 5 | let StorybookComponent = { 6 | bindings: {}, 7 | controllerAs: 'vm', 8 | template, 9 | controller 10 | }; 11 | 12 | export default StorybookComponent; 13 | -------------------------------------------------------------------------------- /src/sb/modules/storybook/storybook.controller.js: -------------------------------------------------------------------------------- 1 | class StorybookController { 2 | constructor($state, $scope, $mdSidenav, storeService) { 3 | this.$state = $state; 4 | this.$scope = $scope; 5 | this.$mdSidenav = $mdSidenav; 6 | 7 | const page = $state.params.state; 8 | this.page = this.activePage = page ? page : 'preview'; 9 | 10 | this.components = storeService.getAllComponents(); 11 | this.componentsList = Object.keys(this.components); 12 | 13 | } 14 | 15 | $postLink() { 16 | if (this.$state.params.responsive === 'true') { 17 | this.toggleResponsive(); 18 | } 19 | if (this.$state.params.split === 'true') { 20 | this.toggleSplitView(); 21 | } 22 | } 23 | 24 | showComponent(page) { 25 | if (!this.splitViewActive) { 26 | return this.activePage === page; 27 | } else { 28 | return this.splitPage === page || page === 'preview'; 29 | } 30 | } 31 | 32 | toggleResponsive() { 33 | this.responsiveActive = !this.responsiveActive; 34 | } 35 | 36 | toggleSplitView() { 37 | const page = this.activePage; 38 | this.splitViewActive = !this.splitViewActive; 39 | if (this.splitViewActive) { 40 | this.splitPage = page !== 'preview' ? page : 'model'; 41 | } 42 | } 43 | 44 | showViewModel(page) { 45 | if (!this.splitViewActive) { 46 | return this.activePage === page; 47 | } else { 48 | return this.splitPage === page; 49 | } 50 | } 51 | 52 | selectPage(page) { 53 | if (!this.splitViewActive) { 54 | this.activePage = this.components[page].title; 55 | } else if (page !== 'preview') { 56 | this.splitPage = this.components[page].title; 57 | } 58 | } 59 | 60 | goTo(k, v) { 61 | let params = this.$state.params; 62 | params[k] = v; 63 | this.$state.go('main.storybook', params, { 64 | reload: false, 65 | location: true, 66 | inherit: false, 67 | notify: false 68 | }); 69 | if (k === 'state') { 70 | this.page = v; 71 | this.selectPage(v); 72 | } 73 | } 74 | 75 | isSidebarOpen() { 76 | return this.$mdSidenav('left').isOpen(); 77 | } 78 | 79 | openSidebar() { 80 | this.$mdSidenav('left').open(); 81 | } 82 | 83 | } 84 | 85 | export default StorybookController; 86 | -------------------------------------------------------------------------------- /src/sb/modules/storybook/storybook.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 11 | menu 12 | 13 | 14 | {{item}} 16 | 17 | 18 | 20 | view_column 21 | 22 | 24 | phonelink 25 | 26 |
27 |
28 | 29 |
30 |
31 |
32 | 33 |
-------------------------------------------------------------------------------- /src/sb/modules/storybook/storybook.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import uiRouter from 'angular-ui-router'; 3 | import homeComponent from './storybook.component'; 4 | import compile from './helper.compile'; 5 | 6 | 7 | let homeModule = angular.module('storybook', [ 8 | uiRouter 9 | ]) 10 | 11 | .config(($stateProvider) => { 12 | "ngInject"; 13 | 14 | $stateProvider 15 | .state('main.storybook', { 16 | url: '/?section&story&point&state&device&responsive&split', 17 | template: '', 18 | reloadOnSearch : false 19 | }); 20 | 21 | }) 22 | 23 | .component('storybook', homeComponent) 24 | 25 | .directive('compile', compile) 26 | 27 | .name; 28 | 29 | export default homeModule; 30 | -------------------------------------------------------------------------------- /src/sb/modules/storybook/storybook.less: -------------------------------------------------------------------------------- 1 | md-nav-ink-bar { 2 | display: none; 3 | } 4 | 5 | #header { 6 | background-color: #fff; 7 | height: 61px; 8 | min-height: 61px; 9 | border-bottom: 1px solid rgba(0,0,0,0.14) 10 | } 11 | 12 | .story__list-wrapper { 13 | border-right: 1px solid rgba(0,0,0,0.14); 14 | background: #fff; 15 | position: relative; 16 | } 17 | 18 | md-nav-bar { 19 | background-color: #fff; 20 | 21 | .md-nav-bar { 22 | border: none; 23 | } 24 | 25 | } 26 | 27 | .md-button.md-icon-button.button__responsive { 28 | color: rgba(0,0,0,0.54); 29 | 30 | &.active { 31 | color: rgb(68,138,255); 32 | } 33 | 34 | } 35 | 36 | .md-button.md-icon-button.button__split-view { 37 | color: rgba(0,0,0,0.54); 38 | 39 | &.active { 40 | color: rgb(68,138,255); 41 | } 42 | 43 | } 44 | 45 | .split__active { 46 | 47 | view, model { 48 | border-left: 1px solid rgba(0, 0, 0, 0.14); 49 | } 50 | 51 | } 52 | 53 | .button__open-sidebar { 54 | 55 | color: rgba(0,0,0,0.54); 56 | 57 | &.hidden { 58 | display: none; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/sb/services/services.module.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import storeService from './store.service'; 3 | 4 | const module = angular.module('sb.services', []); 5 | 6 | module.service('storeService', storeService); 7 | 8 | export default module; -------------------------------------------------------------------------------- /src/sb/services/store.service.js: -------------------------------------------------------------------------------- 1 | export default class StoreService { 2 | 3 | constructor() { 4 | this.components = {}; 5 | } 6 | 7 | component(item) { 8 | 9 | if (!item.title || !item.template) { 10 | throw new Error(`${item.title} is not correct component. Title or template is missing`); 11 | } 12 | 13 | if (this.components[item.title]) { 14 | throw new Error(`Component with ${item.title} is alredy defined. Please take another title`); 15 | } 16 | 17 | this.components[item.title] = item; 18 | 19 | } 20 | 21 | getAllComponents() { 22 | return this.components; 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/sb/styles/app.less: -------------------------------------------------------------------------------- 1 | @import "./highlight.less"; 2 | 3 | .error__message { 4 | font-size: 18px; 5 | justify-content: center; 6 | align-items: center; 7 | display: flex; 8 | color: rgba(0, 0, 0, 0.54); 9 | } -------------------------------------------------------------------------------- /src/sb/styles/highlight.less: -------------------------------------------------------------------------------- 1 | /* 2 | github.com style (c) Vasily Polovnyov 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | color: #333; 10 | } 11 | 12 | .hljs-comment, 13 | .hljs-quote { 14 | color: #998; 15 | font-style: italic; 16 | } 17 | 18 | .hljs-keyword, 19 | .hljs-selector-tag, 20 | .hljs-subst { 21 | color: #333; 22 | font-weight: bold; 23 | } 24 | 25 | .hljs-number, 26 | .hljs-literal, 27 | .hljs-variable, 28 | .hljs-template-variable, 29 | .hljs-tag .hljs-attr { 30 | color: #008080; 31 | } 32 | 33 | .hljs-string, 34 | .hljs-doctag { 35 | color: #d14; 36 | } 37 | 38 | .hljs-title, 39 | .hljs-section, 40 | .hljs-selector-id { 41 | color: #900; 42 | font-weight: bold; 43 | } 44 | 45 | .hljs-subst { 46 | font-weight: normal; 47 | } 48 | 49 | .hljs-type, 50 | .hljs-class .hljs-title { 51 | color: #458; 52 | font-weight: bold; 53 | } 54 | 55 | .hljs-tag, 56 | .hljs-name, 57 | .hljs-attribute { 58 | color: #000080; 59 | font-weight: normal; 60 | } 61 | 62 | .hljs-regexp, 63 | .hljs-link { 64 | color: #009926; 65 | } 66 | 67 | .hljs-symbol, 68 | .hljs-bullet { 69 | color: #990073; 70 | } 71 | 72 | .hljs-built_in, 73 | .hljs-builtin-name { 74 | color: #0086b3; 75 | } 76 | 77 | .hljs-meta { 78 | color: #999; 79 | font-weight: bold; 80 | } 81 | 82 | .hljs-deletion { 83 | background: #fdd; 84 | } 85 | 86 | .hljs-addition { 87 | background: #dfd; 88 | } 89 | 90 | .hljs-emphasis { 91 | font-style: italic; 92 | } 93 | 94 | .hljs-strong { 95 | font-weight: bold; 96 | } -------------------------------------------------------------------------------- /src/stories-api.js: -------------------------------------------------------------------------------- 1 | class StoriesAPI { 2 | 3 | constructor() { 4 | this.sections = {}; 5 | this.mocks = {}; 6 | } 7 | 8 | 9 | /** 10 | * Creta new section 11 | * and return API instance that allow create stories 12 | * 13 | * @param name Section name 14 | * @returns function SB API instance 15 | */ 16 | section(name) { 17 | if (!this.sections[name]) { 18 | this.sections[name] = {}; 19 | } 20 | 21 | let sectionAPI = {}; 22 | 23 | sectionAPI.story = (storyName) => { 24 | let section = this.sections[name]; 25 | let storyAPI = {}; 26 | storyAPI.add = (title, template, model, docs) => { 27 | if (!section[storyName]) { 28 | section[storyName] = []; 29 | } 30 | const id = Math.random().toString(36).substr(2, 9); 31 | section[storyName].push({ title, template, model, docs, id }); 32 | return storyAPI; 33 | } 34 | return storyAPI; 35 | }; 36 | 37 | return sectionAPI; 38 | 39 | } 40 | 41 | 42 | /** 43 | * Get all savad sections 44 | * 45 | * @returns object Sections 46 | */ 47 | getSections() { 48 | return this.sections; 49 | } 50 | 51 | /** 52 | * Get story from store 53 | * 54 | * @param sbObject Should contaie section, story name and point ID. 55 | * @returns object Story 56 | */ 57 | getStory(sbObject) { 58 | try { 59 | // Find story from store 60 | let story = this.sections[sbObject.section][sbObject.story].find(i => i.id === sbObject.id); 61 | 62 | // Check if need load mock for story 63 | if (story && typeof story.model === 'string') { 64 | story.model = this.getMock(story.model); 65 | } 66 | return story; 67 | } catch (e) { 68 | console.log(e); 69 | } 70 | } 71 | 72 | 73 | /** 74 | * Update story with new data 75 | * Used for save tempalate and model 76 | * Use this method if you need to edit any story param 77 | * 78 | * @param sbObject Should contaie section, story name and point ID. 79 | * @param data Story point that need update 80 | */ 81 | updateStory(sbObject, data) { 82 | let storyPoint = this.getStory(sbObject); 83 | storyPoint = data; 84 | } 85 | 86 | /** 87 | * Store mock for stories. 88 | * Mock can be stored as object. 89 | * 90 | * @param key Mock name 91 | * @param value Mock value. 92 | * @param perform Function witch will call with mocked data 93 | * Use it to perform data structure as you need 94 | */ 95 | mock(key, value, perform) { 96 | if (typeof value === 'object') { 97 | this.mocks[key] = perform ? perform(value) : value; 98 | } else { 99 | throw new Error(`Cant't save mock for ${key}. Mock value should be an object. Double check it.`); 100 | } 101 | } 102 | 103 | /** 104 | * Get mock from store 105 | * 106 | * @param key Mock name 107 | * @returns object Mock 108 | */ 109 | getMock(key) { 110 | if (this.mocks[key]) { 111 | return this.mocks[key]; 112 | } else { 113 | throw new Error(`Can't find mock for ${key}`); 114 | } 115 | } 116 | 117 | registerContactCB(cb) { 118 | this.contactCB = cb; 119 | } 120 | 121 | registerReloadCB(cb) { 122 | this.reloadCB = cb; 123 | } 124 | 125 | contact() { 126 | this.contactCB(); 127 | } 128 | 129 | reload() { 130 | if (this.reloadCB) { 131 | this.sections = {}; 132 | setTimeout(() => this.reloadCB(), 0); 133 | } 134 | } 135 | 136 | } 137 | 138 | window.sb = new StoriesAPI(); -------------------------------------------------------------------------------- /src/stories/index.js: -------------------------------------------------------------------------------- 1 | import './mock'; 2 | import docs from './docs.md'; 3 | 4 | let survey = sb.section('The week'); 5 | survey.story('Names of the days of the week') 6 | .add('Sunday', '

{{ vm.sunday }}

', 'week', docs) 7 | .add('Monday', '

{{ vm.monday }}

', 'week', docs) 8 | .add('Tuesday', '

{{ vm.tuesday }}

', 'week', docs) 9 | .add('Wednesday', '

{{ vm.wednesday }}

', 'week', docs) 10 | .add('Thursday', '

{{ vm.thursday }}

', 'week', docs) 11 | .add('Friday', '

{{ vm.friday }}

', 'week', docs) 12 | .add('Saturday', '

{{ vm.saturday }}

', 'week', docs); 13 | 14 | let test = sb.section('Demo 3'); 15 | test.story('Test') 16 | .add('Test', '', { 17 | text: 'Monday' 18 | }); 19 | -------------------------------------------------------------------------------- /stories.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/stories'); -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | module.exports = { 5 | module: { 6 | loaders: [ 7 | { test: /\.js$/, exclude: [/app\/lib/, /node_modules/], loader: 'ng-annotate!babel' }, 8 | { test: /\.html$/, loader: 'raw' }, 9 | { test: /\.less$/, loader: 'style!css!less' }, 10 | { test: /\.css$/, loader: 'style!css' }, 11 | { test: /\.md$/, loader: "html!markdown" } 12 | ] 13 | }, 14 | plugins: [] 15 | }; 16 | -------------------------------------------------------------------------------- /webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var path = require('path'); 3 | var config = require('./webpack.config'); 4 | 5 | config.devtool = 'source-map'; 6 | 7 | config.entry = { 8 | "sb": './src/sb', 9 | "stories": './src/stories-api.js', 10 | "app": './src/app', 11 | "user-stories": './src/stories' 12 | }; 13 | 14 | config.output = { 15 | publicPath: '/', 16 | path: path.join(__dirname, "js"), 17 | filename: "[name].min.js", 18 | library: ["min", "[name]"] 19 | }; 20 | 21 | config.plugins = config.plugins.concat([ 22 | new webpack.HotModuleReplacementPlugin() 23 | ]); 24 | 25 | module.exports = config; 26 | -------------------------------------------------------------------------------- /webpack.dist.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var path = require('path'); 3 | var config = require('./webpack.config'); 4 | 5 | config.entry = { 6 | "sb": ['./src/sb/index.js'], 7 | "stories": ['./src/stories-api.js'], 8 | "ng-helper": ['./src/helpers/angular/helper.js'], 9 | }; 10 | 11 | config.output = { 12 | filename: '[name].js', 13 | publicPath: '', 14 | path: path.resolve(__dirname, 'dist') 15 | }; 16 | 17 | config.plugins = config.plugins.concat([ 18 | 19 | ]); 20 | 21 | module.exports = config; 22 | --------------------------------------------------------------------------------