From 024af849c39a0f7b16cfda7d2dd608c844a61e75 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Tue, 22 Apr 2014 12:35:07 +0100 Subject: [PATCH] docs(examples): use form POST to create Plunkers The previous solution for opening Plunkers from the docs relied on tight coupling between the docs site and the plunkr site, in particular the URL to the example code on the docs server was hard coded in the Plunker site. This change goes back to the old POST method of creating a Plunker, but with a subtle difference: In the very old docs, the content was injected directly into the example HTML at build time. This was easy enough to do as the example actually ran in the current page but also increased the size of the doc page. The new examples are run in completely separate iframes. This new version of showing a Plunker loads the file content for the Plunker from the server by accessing the example's manifest.json file using $http requests. This also has the additional benefit that you can now generate plunkers from examples that are running locally or, frankly, in any folder on any server, such as personal builds on the Jenkins CI server. Closes #7186 Closes #7198 --- docs/app/src/docs.js | 13 +- docs/app/src/examples.js | 292 +++--------------- docs/app/test/docsSpec.js | 1 + .../templates/runnableExample.template.html | 4 +- 4 files changed, 62 insertions(+), 248 deletions(-) diff --git a/docs/app/src/docs.js b/docs/app/src/docs.js index 5c6a76d4e29c..fc1a3e561544 100644 --- a/docs/app/src/docs.js +++ b/docs/app/src/docs.js @@ -1,9 +1,16 @@ angular.module('DocsController', []) -.controller('DocsController', function($scope, $rootScope, $location, $window, $cookies, NG_PAGES, NG_NAVIGATION, NG_VERSION) { +.controller('DocsController', [ + '$scope', '$rootScope', '$location', '$window', '$cookies', 'openPlunkr', + 'NG_PAGES', 'NG_NAVIGATION', 'NG_VERSION', + function($scope, $rootScope, $location, $window, $cookies, openPlunkr, + NG_PAGES, NG_NAVIGATION, NG_VERSION) { + + + $scope.openPlunkr = openPlunkr; $scope.docsVersion = NG_VERSION.isSnapshot ? 'snapshot' : NG_VERSION.version; - + $scope.fold = function(url) { if(url) { $scope.docs_fold = '/notes/' + url; @@ -120,4 +127,4 @@ angular.module('DocsController', []) }); } }); -}); +}]); diff --git a/docs/app/src/examples.js b/docs/app/src/examples.js index 0ad981c957ea..314905601ebf 100644 --- a/docs/app/src/examples.js +++ b/docs/app/src/examples.js @@ -1,65 +1,6 @@ angular.module('examples', []) -.directive('sourceEdit', function(getEmbeddedTemplate) { - return { - template: '
' + - '' + - ' Edit' + - '' + - '' + - '
', - scope: true, - controller: function($scope, $attrs, openJsFiddle, openPlunkr) { - var sources = { - module: $attrs.sourceEdit, - deps: read($attrs.sourceEditDeps), - html: read($attrs.sourceEditHtml), - css: read($attrs.sourceEditCss), - js: read($attrs.sourceEditJs), - json: read($attrs.sourceEditJson), - unit: read($attrs.sourceEditUnit), - scenario: read($attrs.sourceEditScenario) - }; - $scope.fiddle = function(e) { - e.stopPropagation(); - openJsFiddle(sources); - }; - $scope.plunkr = function(e) { - e.stopPropagation(); - openPlunkr(sources); - }; - } - }; - - function read(text) { - var files = []; - angular.forEach(text ? text.split(' ') : [], function(refId) { - // refId is index.html-343, so we need to strip the unique ID when exporting the name - files.push({name: refId.replace(/-\d+$/, ''), content: getEmbeddedTemplate(refId)}); - }); - return files; - } -}) - - -.factory('angularUrls', function($document) { - var urls = {}; - - angular.forEach($document.find('script'), function(script) { - var match = script.src.match(/^.*\/(angular[^\/]*\.js)$/); - if (match) { - urls[match[1].replace(/(\-\d.*)?(\.min)?\.js$/, '.js')] = match[0]; - } - }); - - return urls; -}) - - -.factory('formPostData', function($document) { +.factory('formPostData', ['$document', function($document) { return function(url, fields) { var form = angular.element('
'); angular.forEach(fields, function(value, name) { @@ -71,196 +12,61 @@ angular.module('examples', []) form[0].submit(); form.remove(); }; -}) - +}]) -.factory('prepareDefaultAppModule', function() { - return function(content) { - var deps = []; - angular.forEach(content.deps, function(file) { - if(file.name == 'angular-animate.js') { - deps.push('ngAnimate'); - } - }); - - var moduleName = 'App'; - return { - module : moduleName, - script : "angular.module('" + moduleName + "', [" + - (deps.length ? "'" + deps.join("','") + "'" : "") + "]);\n\n" - }; - }; -}) -.factory('prepareEditorAssetTags', function(angularUrls) { - return function(content, options) { - options = options || {}; - var includeLocalFiles = options.includeLocalFiles; - var html = makeScriptTag(angularUrls['angular.js']); - - var allFiles = [].concat(content.js, content.css, content.html, content.json); - angular.forEach(content.deps, function(file) { - if (file.name !== 'angular.js') { - var isLocal = false; - for(var i=0;i\n'; - } - - function makeCssLinkTag(src) { - return '\n'; - } - }; -}) - - -.factory('openPlunkr', function(templateMerge, formPostData, prepareEditorAssetTags, prepareDefaultAppModule) { - return function(content) { - var hasRouting = false; - angular.forEach(content.deps, function(file) { - hasRouting = hasRouting || file.name == 'angular-route.js'; - }); - var indexHtmlContent = '\n' + - '\n' + - ' \n' + - '{{scriptDeps}}'; +.factory('openPlunkr', ['formPostData', '$http', '$q', function(formPostData, $http, $q) { + return function(exampleFolder) { - if(hasRouting) { - indexHtmlContent += '\n'; - } + var exampleName = 'AngularJS Example'; - indexHtmlContent += '\n' + - ' \n\n' + - '{{indexContents}}\n\n' + - ' \n' + - '\n'; + // Load the manifest for the example + $http.get(exampleFolder + '/manifest.json') + .then(function(response) { + return response.data; + }) + .then(function(manifest) { + var filePromises = []; - indexProp = { - module: content.module, - scriptDeps: prepareEditorAssetTags(content, { includeLocalFiles : true }), - indexContents: content.html[0].content - }; - - var allFiles = [].concat(content.js, content.css, content.html, content.json); - - if(!content.module) { - var moduleData = prepareDefaultAppModule(content); - indexProp.module = moduleData.module; - - var found = false; - angular.forEach(content.js, function(file) { - if(file.name == 'script.js') { - file.content = moduleData.script + file.content; - found = true; - } - }); - if(!found) { - indexProp.scriptDeps += '\n'; - allFiles.push({ - name : 'script.js', - content : moduleData.script + // Build a pretty title for the Plunkr + var exampleNameParts = manifest.name.split('-'); + exampleNameParts.unshift('AngularJS'); + angular.forEach(exampleNameParts, function(part, index) { + exampleNameParts[index] = part.charAt(0).toUpperCase() + part.substr(1); }); - } - } - - var postData = {}; - - angular.forEach(allFiles, function(file, index) { - if (file.content && file.name != 'index.html') { - postData['files[' + file.name + ']'] = file.content; - } - }); - - postData['files[index.html]'] = templateMerge(indexHtmlContent, indexProp); - postData['tags[]'] = "angularjs"; - - postData.private = true; - postData.description = 'AngularJS Example Plunkr'; - - formPostData('http://plnkr.co/edit/?p=preview', postData); - }; -}) - -.factory('openJsFiddle', function(templateMerge, formPostData, prepareEditorAssetTags, prepareDefaultAppModule) { - var HTML = '
\n{{html:2}}
', - CSS = ' \n' + - '{{head:0}}