├── .gitignore ├── .jshintrc ├── CONTRIBUTING.md ├── Gruntfile.js ├── LICENSE ├── README.md ├── demo └── demo.css ├── dist ├── xrayhtml-iframe.js ├── xrayhtml.css └── xrayhtml.js ├── iframe.html ├── index.html ├── package.json ├── src ├── X-rayHTML-iframe.js ├── X-rayHTML.css ├── X-rayHTML.js └── lib │ ├── clipboard.js │ ├── jquery.js │ ├── prism.css │ ├── prism.js │ └── shoestring.js └── test ├── X-rayHTML.html └── X-rayHTML_test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "unused": true, 11 | "boss": true, 12 | "eqnull": true, 13 | "browser": true, 14 | "predef": ["jQuery"] 15 | } 16 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Important notes 4 | Please don't edit files in the `dist` subdirectory as they are generated via grunt. You'll find source code in the `src` subdirectory! 5 | 6 | ### Code style 7 | Regarding code style like indentation and whitespace, **follow the conventions you see used in the source already.** 8 | 9 | ### PhantomJS 10 | While grunt can run the included unit tests via [PhantomJS](http://phantomjs.org/), this shouldn't be considered a substitute for the real thing. Please be sure to test the `test/*.html` unit test file(s) in _actual_ browsers. 11 | 12 | See the [Why does grunt complain that PhantomJS isn't installed?](https://github.com/gruntjs/grunt/blob/master/docs/faq.md#why-does-grunt-complain-that-phantomjs-isnt-installed) guide in the [Grunt FAQ](https://github.com/gruntjs/grunt/blob/master/docs/faq.md) for help with installing or troubleshooting PhantomJS. 13 | 14 | ## Modifying the code 15 | First, ensure that you have the latest [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/) installed. 16 | 17 | Test that grunt is installed globally by running `grunt --version` at the command-line. If grunt isn't installed globally, run `npm install -g grunt` to install the latest version. _You may need to run `sudo npm install -g grunt`._ 18 | 19 | _Note that in Windows, you may have to run `grunt.cmd` instead of `grunt`._ 20 | 21 | 1. Fork and clone the repo. 22 | 1. Run `npm install` to install all dependencies (including grunt). 23 | 1. Run `grunt` to grunt this project. 24 | 25 | Assuming that you don't see any red, you're ready to go. Just be sure to run `grunt` after making any changes, to ensure that nothing is broken. 26 | 27 | ## Submitting pull requests 28 | 29 | 1. Create a new branch, please don't work in your `master` branch directly. 30 | 1. Add failing tests for the change you want to make. Run `grunt` to see the tests fail. 31 | 1. Fix stuff. 32 | 1. Run `grunt` to see if the tests pass. Repeat steps 2-4 until done. 33 | 1. Open `test/*.html` unit test file(s) in actual browser to ensure tests pass everywhere. 34 | 1. Update the documentation to reflect any changes. 35 | 1. Push to your fork and submit a pull request. 36 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 'use strict'; 3 | 4 | 5 | grunt.initConfig({ 6 | pkg: grunt.file.readJSON('package.json'), 7 | banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + 8 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' + 9 | '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + 10 | '* Copyright (c) <%= grunt.template.today("yyyy") %> Filament Group;' + 11 | ' Licensed <%= pkg.license %> */\n', 12 | 13 | concat: { 14 | options: { 15 | banner: '<%= banner %>', 16 | stripBanners: true 17 | }, 18 | js: { 19 | src: [ 20 | '<%= banner %>', 21 | 'src/X-rayHTML.js' 22 | ], 23 | dest: 'dist/<%= pkg.name %>.js' 24 | }, 25 | "iframe-js": { 26 | src: [ 27 | '<%= banner %>', 28 | 'src/X-rayHTML-iframe.js' 29 | ], 30 | dest: 'dist/<%= pkg.name %>-iframe.js' 31 | }, 32 | css: { 33 | src: [ 34 | '<%= banner %>', 35 | 'src/X-rayHTML.css' 36 | ], 37 | dest: 'dist/<%= pkg.name %>.css' 38 | } 39 | }, 40 | 41 | copy: { 42 | libs: { 43 | files: [ 44 | { expand: true, cwd: 'node_modules/prismjs/themes/', src: [ 'prism.css' ], dest: 'src/lib/' }, 45 | { expand: true, cwd: 'node_modules/shoestring/dist/', src: [ 'shoestring.js' ], dest: 'src/lib/' }, 46 | { expand: true, cwd: 'node_modules/jquery/dist/', src: [ 'jquery.js' ], dest: 'src/lib/' }, 47 | { expand: true, cwd: 'node_modules/prismjs/', src: [ 'prism.js' ], dest: 'src/lib/' }, 48 | { expand: true, cwd: 'node_modules/clipboard/dist/', src: [ 'clipboard.js' ], dest: 'src/lib/' } 49 | ] 50 | } 51 | }, 52 | 53 | watch: { 54 | files: 'src/**/*', 55 | tasks: 'default' 56 | }, 57 | 58 | jshint: { 59 | src: { 60 | options: { 61 | jshintrc: '.jshintrc' 62 | }, 63 | src: ['src/*.js'] 64 | } 65 | } 66 | }); 67 | 68 | require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); 69 | 70 | // Default task. 71 | grunt.registerTask('default', ['jshint', 'copy:libs', 'concat']); 72 | }; 73 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Mat Marquis 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | :warning: This project is archived and the repository is no longer maintained. 2 | 3 | # X-rayHTML 4 | 5 | [![Filament Group](http://filamentgroup.com/images/fg-logo-positive-sm-crop.png) ](http://www.filamentgroup.com/) 6 | 7 | A little something to help build documentation pages. 8 | 9 | Instead of dropping in a block of markup to render as a demo, then copying and pasting it into a `pre`/`code` block, then escaping it—then going back and updating both the rendered code and the escaped code should something change: now you just wrap the code you’re rendering in a `div` and it generates a copy/pastable source snippet. Credit to [@ugomobi](http://github.com/ugomobi) for the original idea, which is in use on the [jQuery Mobile docs](http://jquerymobile.com/test). 10 | 11 | ## Dependencies 12 | 13 | 1. jQuery or Shoestring (`./libs`) 14 | 1. prism.js (`./libs`) (Optional) 15 | 16 | ## Install 17 | 18 | This plugin is available on npm as [`xrayhtml`](https://www.npmjs.com/package/xrayhtml). 19 | 20 | ``` 21 | npm install xrayhtml 22 | ``` 23 | 24 | ## Demos 25 | [Here’s the plugin in action](http://filamentgroup.github.com/X-rayHTML/). 26 | 27 | The second set of demos are using the plugin’s “create” event (`create.xrayhtml` by default, but configurable) to bolt on [Prism.js](http://prismjs.com) syntax highlighting. 28 | 29 | ## Getting Started 30 | Download the [production version][min] or the [development version][max], and the [structural CSS][css]. 31 | 32 | [min]: https://raw.github.com/filamentgroup/X-rayHTML/master/dist/X-rayHTML.min.js 33 | [max]: https://raw.github.com/filamentgroup/X-rayHTML/master/dist/X-rayHTML.js 34 | [css]: https://raw.github.com/filamentgroup/X-rayHTML/master/dist/X-rayHTML.css 35 | 36 | In your page: 37 | 38 | ```html 39 | 40 | 41 | ``` 42 | 43 | and 44 | 45 | ```html 46 | 47 | ``` 48 | 49 | There are some config options up at the top of `X-rayHTML.js`: 50 | 51 | ```javascript 52 | var pluginName = "xrayhtml", 53 | o = { 54 | text: { 55 | open: "View Source", 56 | close: "View Demo" 57 | }, 58 | classes: { 59 | button: "btn btn-small", 60 | open: "view-source", 61 | sourcepanel: "source-panel" 62 | }, 63 | initSelector: "[data-" + pluginName + "]", 64 | defaultReveal: "inline" 65 | } 66 | ``` 67 | 68 | By default, functionality is hooked to the `xrayhtml` data attribute. 69 | 70 | `flip` as the value of the `data-xrayhtml` attribute will gives you a snazzy flip-to-reveal animation (browsers without support for 3D tranforms will simply show/hide the code snippet).

71 | 72 | Leaving `data-xrayhtml` valueless or giving it a value of `inline` gives you—predictably enough—code snippets that are visible inline with the rendered code. 73 | 74 | A `pre`/`code` block gets dropped into place, so whitespace inside of the element with that attribute counts the same way. For example, to avoid a bunch of extra whitespace at the start/end of your snippet: 75 | 76 | ```html 77 |
84 | ``` 85 | 86 | ## iframe support 87 | 88 | You can load your examples into an iframe using the `data-xrayhtml-iframe` 89 | attribute. This is useful for examples that have media queries which depend on 90 | the viewport width and which may be in pages where the examples are not full width (e.g. when you have documentation navigation on the left). 91 | 92 | ```html 93 |
94 | ... 95 | ``` 96 | 97 | Critically, the value of the attribute should point to a URL which serves a document that includes all of the necessary assets to handle the example properly. 98 | 99 | That document must also include the `xrayhtml-iframe.js` found in the `dist` 100 | directory. The JS will listen for messages from the `xrayhtml.js` in the parent 101 | page to so that it can communicate dimensions for the iframe during initial load and also during `resize` events. 102 | 103 | Following the example above, you might include the following in `/xray.html` 104 | 105 | ```html 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | ``` 116 | -------------------------------------------------------------------------------- /demo/demo.css: -------------------------------------------------------------------------------- 1 | @charset utf-8; 2 | 3 | /* Demo 4 | -------------------------- */ 5 | .sub, h2 { 6 | font-family: sans-serif; 7 | } 8 | .sub { 9 | border-bottom: 1px solid #ddd; 10 | padding: .25em 0; 11 | } 12 | h2 { 13 | font-size: 1.1em; 14 | } 15 | 16 | .btn { 17 | background-color: #fefefe; 18 | background-image: -webkit-linear-gradient( top, rgba( 255,255,255,.1 ) 0%, rgba( 255,255,255,.1 ) 50%, rgba( 170,170,170,.1 ) 55%, rgba( 120,120,120,.15 ) 100% ); 19 | background-image: -moz-linear-gradient( top, rgba( 255,255,255,.1 ) 0%, rgba( 255,255,255,.1 ) 50%, rgba( 170,170,170,.1 ) 55%, rgba( 120,120,120,.15 ) 100% ); 20 | background-image: linear-gradient( top, rgba( 255,255,255,.1 ) 0%, rgba( 255,255,255,.1 ) 50%, rgba( 170,170,170,.1 ) 55%, rgba( 120,120,120,.15 ) 100% ); 21 | border: 1px solid #ccc; 22 | border-radius: .4em; 23 | color: #308bd3; 24 | cursor: pointer; 25 | display: block; 26 | font: bold 14px/1 sans-serif; 27 | padding: .6em 0 .5em 0; 28 | position: relative; 29 | text-align: center; 30 | text-decoration: none; 31 | text-transform: capitalize; 32 | text-shadow: 0 1px 0 #fff; 33 | width: 100%; 34 | 35 | -webkit-box-sizing: border-box; 36 | -moz-box-sizing: border-box; 37 | -ms-box-sizing: border-box; 38 | box-sizing: border-box; 39 | } 40 | 41 | 42 | .method-inline .btn { 43 | width: auto; 44 | display: inline-block; 45 | position: absolute; 46 | right: 0; 47 | bottom: 0; 48 | padding-left: 1em; 49 | padding-right: 1em; 50 | border-radius: 5px 0 0 0; 51 | border-width: 1px 0 0 1px; 52 | } 53 | 54 | .method-flip .btn-copy { 55 | border-width: 0 0 1px 0; 56 | border-radius: 0; 57 | } 58 | .btn-small { 59 | display: inline-block; 60 | font-size: .8em; 61 | padding: .4em 2% .35em 2%; 62 | width: auto; 63 | } 64 | aside { 65 | padding: .5em; 66 | } 67 | blockquote { 68 | font-size: 1.6em; 69 | margin: 0; 70 | position: relative; 71 | } 72 | blockquote:before { 73 | color: #ccc; 74 | content: "“"; 75 | font-size: 4em; 76 | left: 0; 77 | line-height: .25; 78 | position: absolute; 79 | top: 0; 80 | z-index: 1; 81 | } 82 | blockquote p { 83 | position: relative; 84 | margin: 1em; 85 | z-index: 2; 86 | } 87 | address { 88 | font-size: 1.2em; 89 | } 90 | cite { 91 | font-size: 1.1em; 92 | } 93 | /* Logo */ 94 | .header { 95 | background: #247201 url(http://filamentgroup.com/images/headerbg-new.jpg) no-repeat bottom left; 96 | } 97 | #fg-logo { 98 | text-indent: -9999px; 99 | margin: 0 auto; 100 | width: 287px; 101 | height: 52px; 102 | background-image: url(http://filamentgroup.com/images/fg-logo-icon.png); 103 | } 104 | @media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5){ 105 | #fg-logo { 106 | background-size: 287px 52px; 107 | background-image: url(http://filamentgroup.com/images/fg-logo-icon-lrg.png); 108 | } 109 | } 110 | 111 | -------------------------------------------------------------------------------- /dist/xrayhtml-iframe.js: -------------------------------------------------------------------------------- 1 | /*! X-rayHTML - v2.3.0 - 2019-06-28 2 | * https://github.com/filamentgroup/x-rayhtml 3 | * Copyright (c) 2019 Filament Group; Licensed MIT */ 4 | (function(){ 5 | 6 | // Empty and exec the ready queue 7 | var ready = false, 8 | readyQueue = [], 9 | runReady = function(){ 10 | if( !ready ){ 11 | while( readyQueue.length ){ 12 | readyQueue.shift().call( document ); 13 | } 14 | ready = true; 15 | } 16 | }; 17 | 18 | // The following is borrowed wholesale from shoestring 19 | // https://github.com/filamentgroup/shoestring/blob/master/src/core/ready.js 20 | function onReady( callback ){ 21 | if( ready && callback ){ 22 | callback.call( document ); 23 | } else if( callback ){ 24 | readyQueue.push( callback ); 25 | } else { 26 | runReady(); 27 | } 28 | 29 | return [document]; 30 | } 31 | 32 | 33 | // Quick IE8 shiv 34 | if( !window.addEventListener ){ 35 | window.addEventListener = function( evt, cb ){ 36 | return window.attachEvent( "on" + evt, cb ); 37 | }; 38 | } 39 | 40 | // reset ready state with new content for the iframe 41 | // TODO bind to load event for other items, e.g. stylesheets 42 | function resetReady(imageCount){ 43 | ready = false; 44 | var eventCounter = 0; 45 | 46 | if(! imageCount ){ 47 | runReady(); 48 | return; 49 | } 50 | 51 | var eventIncrement = function(event){ 52 | if( event.target.tagName !== 'IMG' ){ 53 | return; 54 | } 55 | 56 | eventCounter++; 57 | 58 | // all of the images and the load event 59 | if(eventCounter === imageCount){ 60 | runReady(); 61 | } 62 | }; 63 | 64 | document.body.addEventListener("load", eventIncrement, true); 65 | } 66 | 67 | function sendSize( iframeid ){ 68 | window 69 | .parent 70 | .postMessage('{ "iframeid": ' + iframeid + ', "iframeheight" : ' + 71 | document.documentElement.offsetHeight + 72 | '}', "*"); 73 | } 74 | 75 | var id; 76 | 77 | window.addEventListener("message", function( event ){ 78 | // same host check 79 | var origin = event.origin || event.originalEvent.origin; 80 | var allowedOrigin = new RegExp( "https?:\/\/" + location.host ); 81 | if( !origin.match( allowedOrigin ) ){ 82 | return; 83 | } 84 | 85 | var data = event.data || event.originalEvent.data; 86 | var elem = document.querySelector(data.selector || "body"); 87 | var fragment = document.createElement("div"); 88 | fragment.innerHTML = data.html; 89 | 90 | // the document is now not ready and needs to wait until everything 91 | // new has loaded (proxy: when all the images have loaded) 92 | resetReady(fragment.querySelectorAll("img").length); 93 | 94 | // use the passed information to populate the page 95 | for(var x = 0; x < fragment.children.length; x++) { 96 | elem.append(fragment.children[0]); 97 | } 98 | 99 | id = data.id; 100 | 101 | // wait until everything loads to calc the height and communicate it 102 | // TODO it would be better to bind to the load of the styles at least 103 | onReady(function(){ 104 | sendSize(id); 105 | }); 106 | }, false); 107 | 108 | var minInterval = 300; 109 | var resized = false; 110 | window.addEventListener("resize", function(){ 111 | if(resized){ return; } 112 | sendSize(id); 113 | resized = true; 114 | setTimeout(function(){ resized = false; }, minInterval); 115 | }); 116 | })(); 117 | -------------------------------------------------------------------------------- /dist/xrayhtml.css: -------------------------------------------------------------------------------- 1 | /*! X-rayHTML - v2.3.0 - 2019-06-28 2 | * https://github.com/filamentgroup/x-rayhtml 3 | * Copyright (c) 2019 Filament Group; Licensed MIT */ 4 | .xrayhtml { 5 | border: 1px solid rgba(0,0,0,.1); 6 | border-radius: .3em; 7 | margin: 1.5em 0 2.5em 0; 8 | padding: 1em 1em 2em; 9 | } 10 | .xrayhtml.xray-copy { 11 | position: relative; 12 | } 13 | .xrayhtml .xraytitle { 14 | text-transform: uppercase; 15 | letter-spacing: 1px; 16 | font: .75em sans-serif; 17 | color: rgba(0,0,0,.5); 18 | background-color: #fff; 19 | border-radius: 3px; 20 | display: inline-block; 21 | position: relative; 22 | top: -2.166666667em; /* 26px */ 23 | padding-left: .1em; 24 | padding-right: .1em; 25 | z-index: 3; 26 | margin: 0; 27 | } 28 | .xrayhtml.method-flip:before { 29 | background-color: rgba(255,255,255,.6); 30 | } 31 | .xrayhtml .source-panel { 32 | background: #f7f7f7; 33 | margin-top: 2em; 34 | tab-size: 2; 35 | } 36 | .xrayhtml .source-panel pre { 37 | margin: 0; 38 | padding: 16px; 39 | border-radius: 0 0 .3em .3em; 40 | } 41 | .xrayhtml .source-panel code { 42 | white-space: pre-wrap; 43 | } 44 | .xrayhtml.method-flip .source-panel { 45 | margin-top: 0; 46 | border-radius: 0.3em; 47 | } 48 | .xrayhtml.method-inline .source-panel { 49 | margin: 2em -1em -2em -1em !important; /* Prism override. */ 50 | border-top: 1px solid rgba(0,0,0,.1); 51 | border-radius: 0 0 .3em .3em; 52 | } 53 | /* Prism override. */ 54 | .xrayhtml .source-panel code.language-markup { 55 | white-space: pre-wrap !important; 56 | } 57 | 58 | .xrayhtml.antipattern { 59 | border-color: #C9282D; 60 | } 61 | .xrayhtml.antipattern .xraytitle { 62 | color: #d75e72; 63 | font-weight: 700; 64 | } 65 | 66 | /* Flip Animation */ 67 | .xrayhtml.method-flip { 68 | padding: 0; 69 | } 70 | .method-flip { 71 | -webkit-perspective: 2500px; 72 | -moz-perspective: 2500px; 73 | perspective: 2500px; 74 | } 75 | .method-flip .source-panel { 76 | position: absolute; 77 | top: 0; 78 | left: 0; 79 | width: 100%; 80 | height: 100%; 81 | overflow-x: auto; 82 | } 83 | .method-flip .snippet { 84 | margin: 0; 85 | position: relative; 86 | top: 0; 87 | left: 0; 88 | z-index: 2; 89 | min-height: 100%; 90 | background-color: #fff; 91 | padding: 1em; 92 | 93 | -webkit-transform: rotateY(0deg); 94 | -webkit-transform-style: preserve-3d; 95 | -webkit-backface-visibility: hidden; 96 | 97 | -moz-transform: rotateY(0deg); 98 | -moz-transform-style: preserve-3d; 99 | -moz-backface-visibility: hidden; 100 | 101 | -webkit-transition: -webkit-transform .4s ease-in-out; 102 | -moz-transition: -moz-transform .4s ease-in-out; 103 | } 104 | .method-flip.view-source .snippet { 105 | z-index: 1; 106 | -webkit-transform: rotateY(180deg); 107 | -moz-transform: rotateY(180deg); 108 | } 109 | .method-flip .source-panel { 110 | -webkit-transform: rotateY(-180deg); 111 | -webkit-backface-visibility: hidden; 112 | 113 | -moz-transform: rotateY(-180deg); 114 | -moz-backface-visibility: hidden; 115 | 116 | -moz-transition: all .4s ease-in-out; 117 | -webkit-transition: all .4s ease-in-out; 118 | } 119 | .method-flip.view-source .source-panel { 120 | z-index: 2; 121 | -webkit-transform: rotateY(0deg); 122 | -moz-transform: rotateY(0deg); 123 | } 124 | 125 | .method-flip.view-source .xraytitle { 126 | background-color: transparent; 127 | background-image: linear-gradient( 128 | to bottom, 129 | transparent, 130 | transparent 40%, 131 | #ffffff 40%, 132 | transparent); 133 | } 134 | 135 | iframe.xray-iframe { 136 | border: 0; 137 | width: 100% 138 | } -------------------------------------------------------------------------------- /dist/xrayhtml.js: -------------------------------------------------------------------------------- 1 | /*! X-rayHTML - v2.3.0 - 2019-06-28 2 | * https://github.com/filamentgroup/x-rayhtml 3 | * Copyright (c) 2019 Filament Group; Licensed MIT */ 4 | window.jQuery = window.jQuery || window.shoestring; 5 | 6 | (function( $ ) { 7 | var xrayiframeid = 0; 8 | var pluginName = "xrayhtml", 9 | o = { 10 | text: { 11 | open: "View Source", 12 | close: "View Demo", 13 | titlePrefix: "Example", 14 | antipattern: "Do Not Use" 15 | }, 16 | classes: { 17 | button: "btn btn-small btn-xrayhtml-flipsource", 18 | open: "view-source", 19 | sourcepanel: "source-panel", 20 | title: "xraytitle", 21 | antipattern: "antipattern" 22 | }, 23 | initSelector: "[data-" + pluginName + "]", 24 | defaultReveal: "inline" 25 | }, 26 | methods = { 27 | _create: function() { 28 | return $( this ).each(function() { 29 | var init = $( this ).data( "init." + pluginName ); 30 | 31 | if( init ) { 32 | return false; 33 | } 34 | 35 | $( this ) 36 | .data( "init." + pluginName, true ) 37 | [ pluginName ]( "_init" ) 38 | .trigger( "create." + pluginName ); 39 | }); 40 | }, 41 | _init: function() { 42 | var $self = $(this); 43 | 44 | $self.data( "id." + pluginName, xrayiframeid++); 45 | 46 | var method = $( this ).attr( "data-" + pluginName ) || o.defaultReveal; 47 | 48 | if( method === "flip" ) { 49 | $( this )[ pluginName ]( "_createButton" ); 50 | } 51 | 52 | $( this ) 53 | .addClass( pluginName + " " + "method-" + method ) 54 | [ pluginName ]( "_createSource" ); 55 | 56 | // use an iframe to host the source 57 | if( $(this).is("[data-" + pluginName + "-iframe]") ){ 58 | 59 | // grab the snippet html to ship to the iframe 60 | var snippetHTML = $(this).find(".snippet").html(); 61 | 62 | // grab the url of the iframe to load 63 | var url = $(this).attr("data-" + pluginName + "-iframe"); 64 | 65 | // grab the selector for the element in the iframe to put the html in 66 | var selector = $(this).attr("data-" + pluginName + "-iframe-target"); 67 | 68 | // create the iframe element, so we can bind to the load event 69 | var $iframe = $("