mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-20 04:11:51 +00:00
feat(docs): add full offline support
This commit is contained in:
parent
bee78a8492
commit
9dea9de449
7 changed files with 165 additions and 70 deletions
19
Rakefile
19
Rakefile
|
|
@ -221,8 +221,14 @@ end
|
||||||
|
|
||||||
|
|
||||||
desc 'Generate docs'
|
desc 'Generate docs'
|
||||||
task :docs do
|
task :docs => [:init] do
|
||||||
`node docs/src/gen-docs.js`
|
`node docs/src/gen-docs.js`
|
||||||
|
File.open(path_to('docs/.htaccess'), File::RDWR) do |f|
|
||||||
|
text = f.read
|
||||||
|
f.truncate 0
|
||||||
|
f.rewind
|
||||||
|
f.write text.sub('"NG_VERSION_FULL"', NG_VERSION.full)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -250,19 +256,28 @@ task :package => [:clean, :compile, :docs] do
|
||||||
|
|
||||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/index.html", File::RDWR) do |f|
|
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/index.html", File::RDWR) do |f|
|
||||||
text = f.read
|
text = f.read
|
||||||
|
f.truncate 0
|
||||||
f.rewind
|
f.rewind
|
||||||
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
||||||
end
|
end
|
||||||
|
|
||||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/docs-scenario.html", File::RDWR) do |f|
|
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/docs-scenario.html", File::RDWR) do |f|
|
||||||
text = f.read
|
text = f.read
|
||||||
|
f.truncate 0
|
||||||
f.rewind
|
f.rewind
|
||||||
f.write text.sub('angular-scenario.js', "angular-scenario-#{NG_VERSION.full}.js")
|
f.write text.sub('angular-scenario.js', "angular-scenario-#{NG_VERSION.full}.js")
|
||||||
end
|
end
|
||||||
|
|
||||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/appcache.manifest", File::RDWR) do |f|
|
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/appcache.manifest", File::RDWR) do |f|
|
||||||
|
|
||||||
text = f.read
|
text = f.read
|
||||||
|
f.truncate 0
|
||||||
|
f.rewind
|
||||||
|
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
||||||
|
end
|
||||||
|
|
||||||
|
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/appcache-offline.manifest", File::RDWR) do |f|
|
||||||
|
text = f.read
|
||||||
|
f.truncate 0
|
||||||
f.rewind
|
f.rewind
|
||||||
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,13 @@ function appCache(path) {
|
||||||
if(!path) {
|
if(!path) {
|
||||||
return appCacheTemplate();
|
return appCacheTemplate();
|
||||||
}
|
}
|
||||||
var blackList = ["offline.html",
|
var blackList = ["build/docs/offline.html",
|
||||||
"sitemap.xml",
|
"build/docs/sitemap.xml",
|
||||||
"robots.txt",
|
"build/docs/robots.txt",
|
||||||
"docs-scenario.html",
|
"build/docs/docs-scenario.html",
|
||||||
"docs-scenario.js",
|
"build/docs/docs-scenario.js",
|
||||||
"appcache.manifest"
|
"build/docs/appcache.manifest",
|
||||||
|
"build/docs/.htaccess"
|
||||||
];
|
];
|
||||||
|
|
||||||
var result = ["CACHE MANIFEST",
|
var result = ["CACHE MANIFEST",
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ function writeTheRest(writesFuture) {
|
||||||
writesFuture.push(writer.output('docs-scenario.js', ngdoc.scenarios(docs)));
|
writesFuture.push(writer.output('docs-scenario.js', ngdoc.scenarios(docs)));
|
||||||
writesFuture.push(writer.output('robots.txt', 'Sitemap: http://docs.angularjs.org/sitemap.xml\n'));
|
writesFuture.push(writer.output('robots.txt', 'Sitemap: http://docs.angularjs.org/sitemap.xml\n'));
|
||||||
writesFuture.push(writer.output('appcache.manifest',appCache()));
|
writesFuture.push(writer.output('appcache.manifest',appCache()));
|
||||||
|
writesFuture.push(writer.copyTpl('.htaccess'));
|
||||||
|
|
||||||
writesFuture.push(writer.merge(['docs.js',
|
writesFuture.push(writer.merge(['docs.js',
|
||||||
'doc_widgets.js'],
|
'doc_widgets.js'],
|
||||||
|
|
|
||||||
|
|
@ -1,57 +1,11 @@
|
||||||
Options +Indexes
|
## OFFLINE SUPPORT ##
|
||||||
IndexIgnore favicon.ico
|
|
||||||
|
# These rules tell apache to check if there is a cookie called "offline", with value set to the
|
||||||
|
# current angular version. If this rule matches the appcache-offline.manifest will be served for
|
||||||
|
# requests to appcache.manifest
|
||||||
|
#
|
||||||
|
# This file must be processed by Rake in order to replace %ANGULAR_VERSION% with the actual version.
|
||||||
|
|
||||||
RewriteEngine on
|
RewriteEngine on
|
||||||
|
RewriteCond %{HTTP_COOKIE} ng-offline="NG_VERSION_FULL"
|
||||||
# Enable Crawling of AJAX apps.
|
RewriteRule appcache.manifest appcache-offline.manifest
|
||||||
# See: http://code.google.com/web/ajaxcrawling/docs/getting-started.html
|
|
||||||
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=\/(.*)$
|
|
||||||
RewriteRule ^(.*)$ /$1/%1.html?
|
|
||||||
|
|
||||||
# Map versiond angular files to root folder.
|
|
||||||
RewriteRule ^angular([\-\w]+)(\d+\.\d+\.\d+)(.*)$ /$2/angular$1$2$3
|
|
||||||
# Map 1.2.3/docs to 1.2.3/docs-1.2.3/ so that we don't need the version in the URL twice
|
|
||||||
RewriteRule ^(\d+\.\d+\.\d+)/docs/(.*)$ /$1/docs-$1/$2
|
|
||||||
|
|
||||||
# If the user has forgot the trailing slash than add it through redirect
|
|
||||||
RewriteRule ^latest$ /latest/ [R]
|
|
||||||
RewriteRule ^latest/docs$ /latest/docs/ [R]
|
|
||||||
|
|
||||||
# To change the latest version just change this line.
|
|
||||||
# IMPORTANT: the order of lines matters, do not move to top!
|
|
||||||
RewriteRule ^latest/(.*)$ /0.9.17/$1
|
|
||||||
|
|
||||||
# If the request comes on http://docs.angularjs.org then point it to latest/docs
|
|
||||||
RewriteCond %{HTTP_HOST} ^docs\.angularjs\.org$
|
|
||||||
RewriteCond %{REQUEST_URI} !^/\d+\.\d+\.\d+
|
|
||||||
RewriteCond %{REQUEST_URI} !^/latest
|
|
||||||
RewriteCond %{REQUEST_URI} !^/angular-
|
|
||||||
RewriteCond %{REQUEST_URI} !^/favicon.ico
|
|
||||||
RewriteRule ^(.*)$ /latest/docs/$1
|
|
||||||
|
|
||||||
## PERFORMANCE ##
|
|
||||||
|
|
||||||
ExpiresActive On
|
|
||||||
|
|
||||||
# cache js files for one year
|
|
||||||
<FilesMatch "^angular-(ie-compat-)?[\d\.]+(\.min)?\.js">
|
|
||||||
ExpiresDefault "access plus 1 year"
|
|
||||||
</FilesMatch>
|
|
||||||
|
|
||||||
# don't cache appcache manifests
|
|
||||||
<FilesMatch "\.manifest$">
|
|
||||||
ExpiresDefault "access"
|
|
||||||
</FilesMatch>
|
|
||||||
|
|
||||||
# cache everything else for 1h
|
|
||||||
ExpiresDefault "access plus 60 minutes"
|
|
||||||
|
|
||||||
|
|
||||||
# compression
|
|
||||||
SetOutputFilter DEFLATE
|
|
||||||
Header set Vary "Accept-Encoding"
|
|
||||||
|
|
||||||
|
|
||||||
# content types
|
|
||||||
AddType application/javascript js
|
|
||||||
AddType text/cache-manifest .manifest
|
|
||||||
|
|
||||||
|
|
@ -83,6 +83,12 @@ li {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#offline{
|
||||||
|
text-decoration:underline;
|
||||||
|
cursor:pointer;
|
||||||
|
color:blue;
|
||||||
|
}
|
||||||
|
|
||||||
#copyright {
|
#copyright {
|
||||||
float:right;
|
float:right;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|
@ -317,3 +323,78 @@ li {
|
||||||
display: inline;
|
display: inline;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* subpages */
|
||||||
|
|
||||||
|
#fader {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: black;
|
||||||
|
opacity: 0.8;
|
||||||
|
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
|
||||||
|
filter: alpha(opacity=80);
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subpage {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subpage > div {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 729px;
|
||||||
|
margin-top: -140px;
|
||||||
|
margin-left: -365px;
|
||||||
|
z-index: 3;
|
||||||
|
background-color: #7989D6;
|
||||||
|
border-radius: 15px;
|
||||||
|
-moz-border-radius: 15px;
|
||||||
|
-webkit-border-radius: 15px;
|
||||||
|
box-shadow: 4px 4px 6px #48577D;
|
||||||
|
-webkit-box-shadow: 4px 4px 6px #48577D;
|
||||||
|
-moz-box-shadow: 4px 4px 6px #48577D;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subpage h2 {
|
||||||
|
height: 1.8em;
|
||||||
|
-moz-border-radius-topright: 15px;
|
||||||
|
-moz-border-radius-topleft: 15px;
|
||||||
|
border-radius-topright: 15px;
|
||||||
|
border-radius-topleft: 15px;
|
||||||
|
-webkit-border-top-right-radius: 15px;
|
||||||
|
-webkit-border-top-left-radius: 15px;
|
||||||
|
border-top-right-radius: 15px;
|
||||||
|
border-top-left-radius: 15px;
|
||||||
|
padding: 0.6em 0 0 1em;
|
||||||
|
margin: 0;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subpage > div > a {
|
||||||
|
color: black;
|
||||||
|
float: right;
|
||||||
|
margin: -40px 10px;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subpage > div > a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subpage > div > p {
|
||||||
|
background-color: white;
|
||||||
|
padding: 0.5em 1em 0.5em 1em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cacheButton {
|
||||||
|
margin: 0em 2em 1em 0em;
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,17 @@
|
||||||
var HAS_HASH = /#/;
|
DocsController.$inject = ['$location', '$browser', '$window', '$cookies'];
|
||||||
DocsController.$inject = ['$location', '$browser', '$window'];
|
function DocsController($location, $browser, $window, $cookies) {
|
||||||
function DocsController($location, $browser, $window) {
|
|
||||||
window.$root = this.$root;
|
window.$root = this.$root;
|
||||||
var self = this;
|
|
||||||
|
var self = this,
|
||||||
|
OFFLINE_COOKIE_NAME = 'ng-offline',
|
||||||
|
HAS_HASH = /#/;
|
||||||
|
|
||||||
this.$location = $location;
|
this.$location = $location;
|
||||||
|
|
||||||
self.versionNumber = angular.version.full;
|
self.versionNumber = angular.version.full;
|
||||||
self.version = angular.version.full + " " + angular.version.codeName;
|
self.version = angular.version.full + " " + angular.version.codeName;
|
||||||
self.cookieName = "angularPref";
|
|
||||||
self.subpage = false;
|
self.subpage = false;
|
||||||
self.offlineEnabled = (document.cookie.indexOf(self.cookieName) !== -1);
|
self.offlineEnabled = ($cookies[OFFLINE_COOKIE_NAME] == angular.version.full);
|
||||||
|
|
||||||
if (!HAS_HASH.test($location.href)) {
|
if (!HAS_HASH.test($location.href)) {
|
||||||
$location.hashPath = '!/api';
|
$location.hashPath = '!/api';
|
||||||
|
|
@ -73,6 +75,27 @@ function DocsController($location, $browser, $window) {
|
||||||
"subject=" + escape("Feedback on " + $location.href) + "&" +
|
"subject=" + escape("Feedback on " + $location.href) + "&" +
|
||||||
"body=" + escape("Hi there,\n\nI read " + $location.href + " and wanted to ask ....");
|
"body=" + escape("Hi there,\n\nI read " + $location.href + " and wanted to ask ....");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** stores a cookie that is used by apache to decide which manifest ot send */
|
||||||
|
this.enableOffline = function() {
|
||||||
|
//The cookie will be good for one year!
|
||||||
|
var date = new Date();
|
||||||
|
date.setTime(date.getTime()+(365*24*60*60*1000));
|
||||||
|
var expires = "; expires="+date.toGMTString();
|
||||||
|
var value = angular.version.full;
|
||||||
|
document.cookie = OFFLINE_COOKIE_NAME + "="+value+expires+"; path=" + $location.path;
|
||||||
|
|
||||||
|
//force the page to reload so server can serve new manifest file
|
||||||
|
window.location.reload(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// bind escape to hash reset callback
|
||||||
|
angular.element(window).bind('keydown', function(e) {
|
||||||
|
if (e.keyCode === 27) {
|
||||||
|
self.subpage = false;
|
||||||
|
self.$eval();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// prevent compilation of code
|
// prevent compilation of code
|
||||||
|
|
|
||||||
|
|
@ -77,10 +77,30 @@
|
||||||
ng:href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
|
ng:href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
|
||||||
ng:bind-template="v{{version}}">
|
ng:bind-template="v{{version}}">
|
||||||
</a>
|
</a>
|
||||||
|
<a ng:hide="offlineEnabled" ng:click ="subpage = true">(enable offline support)</a>
|
||||||
|
<span ng:show="offlineEnabled">(offline support enabled)</span>
|
||||||
<span id="copyright">© 2010-2011 AngularJS</span>
|
<span id="copyright">© 2010-2011 AngularJS</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="fader" ng:show="subpage"></div>
|
||||||
|
<div id="subpage" ng:show="subpage">
|
||||||
|
<div>
|
||||||
|
<h2>Would you like full offline support for this AngularJS Docs App?</h2>
|
||||||
|
<a ng:click="subpage=false">✕</a>
|
||||||
|
<p>
|
||||||
|
If you want to be able to access the entire AngularJS documentation offline, click the
|
||||||
|
button below. This will reload the current page and trigger background downloads of all the
|
||||||
|
necessary files (approximately 3.5MB). The next time you load the docs, the browser will
|
||||||
|
use these cached files.
|
||||||
|
<br><br>
|
||||||
|
This feature is supported on all modern browsers, except for IE9 which lacks application
|
||||||
|
cache support.
|
||||||
|
</p>
|
||||||
|
<button id="cacheButton" ng:click="enableOffline()">Let me have them all!</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="syntaxhighlighter/syntaxhighlighter-combined.js"></script>
|
<script src="syntaxhighlighter/syntaxhighlighter-combined.js"></script>
|
||||||
<!-- jquery place holder -->
|
<!-- jquery place holder -->
|
||||||
<script src="../angular.min.js" ng:autobind></script>
|
<script src="../angular.min.js" ng:autobind></script>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue