mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
resources concat and minify in production
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package com.commafeed.frontend;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.enterprise.inject.spi.BeanManager;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
@@ -8,6 +10,7 @@ import javax.servlet.http.Cookie;
|
||||
import org.apache.wicket.Application;
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.Page;
|
||||
import org.apache.wicket.RuntimeConfigurationType;
|
||||
import org.apache.wicket.Session;
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.authentication.strategy.DefaultAuthenticationStrategy;
|
||||
@@ -47,7 +50,16 @@ import com.commafeed.frontend.utils.exception.DisplayExceptionPage;
|
||||
|
||||
public class CommaFeedApplication extends AuthenticatedWebApplication {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(CommaFeedApplication.class);
|
||||
private static Logger log = LoggerFactory
|
||||
.getLogger(CommaFeedApplication.class);
|
||||
|
||||
public CommaFeedApplication() {
|
||||
super();
|
||||
String prod = ResourceBundle.getBundle("application").getString(
|
||||
"production");
|
||||
setConfigurationType(Boolean.valueOf(prod) ? RuntimeConfigurationType.DEPLOYMENT
|
||||
: RuntimeConfigurationType.DEVELOPMENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<title>CommaFeed</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
|
||||
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<wicket:child />
|
||||
|
||||
@@ -5,12 +5,12 @@ import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.wicket.RuntimeConfigurationType;
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.markup.head.filter.HeaderResponseContainer;
|
||||
import org.apache.wicket.markup.html.WebPage;
|
||||
import org.apache.wicket.model.Model;
|
||||
import org.apache.wicket.resource.TextTemplateResourceReference;
|
||||
|
||||
import com.commafeed.backend.dao.FeedCategoryDAO;
|
||||
import com.commafeed.backend.dao.FeedDAO;
|
||||
@@ -22,7 +22,7 @@ import com.commafeed.backend.dao.UserRoleDAO;
|
||||
import com.commafeed.backend.dao.UserSettingsDAO;
|
||||
import com.commafeed.backend.model.ApplicationSettings;
|
||||
import com.commafeed.backend.services.ApplicationSettingsService;
|
||||
import com.commafeed.frontend.references.bootstrap.BootstrapReference;
|
||||
import com.commafeed.frontend.utils.WicketUtils;
|
||||
import com.google.api.client.util.Maps;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@@ -62,16 +62,27 @@ public abstract class BasePage extends WebPage {
|
||||
@Override
|
||||
public void renderHead(IHeaderResponse response) {
|
||||
super.renderHead(response);
|
||||
BootstrapReference.renderHead(response);
|
||||
|
||||
if (getApplication().getConfigurationType() == RuntimeConfigurationType.DEPLOYMENT) {
|
||||
response.render(JavaScriptHeaderItem.forUrl("wro/all.js"));
|
||||
response.render(CssHeaderItem.forUrl("wro/all.css"));
|
||||
} else {
|
||||
response.render(JavaScriptHeaderItem.forUrl("wro/lib.js"));
|
||||
response.render(CssHeaderItem.forUrl("wro/lib.css"));
|
||||
|
||||
response.render(JavaScriptHeaderItem.forUrl("js/welcome.js"));
|
||||
response.render(JavaScriptHeaderItem.forUrl("js/main.js"));
|
||||
response.render(JavaScriptHeaderItem.forUrl("js/controllers.js"));
|
||||
response.render(JavaScriptHeaderItem.forUrl("js/directives.js"));
|
||||
response.render(JavaScriptHeaderItem.forUrl("js/services.js"));
|
||||
response.render(CssHeaderItem.forUrl("css/app.css"));
|
||||
}
|
||||
|
||||
final ApplicationSettings settings = applicationSettingsService.get();
|
||||
if (StringUtils.isNotBlank(settings.getGoogleAnalyticsTrackingCode())) {
|
||||
Map<String, Object> vars = Maps.newHashMap();
|
||||
vars.put("trackingCode", settings.getGoogleAnalyticsTrackingCode());
|
||||
response.render(JavaScriptHeaderItem
|
||||
.forReference(new TextTemplateResourceReference(
|
||||
BasePage.class, "analytics.js", Model.ofMap(vars))));
|
||||
|
||||
WicketUtils.loadJS(response, BasePage.class, "analytics", vars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,26 +2,13 @@ package com.commafeed.frontend.pages;
|
||||
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
|
||||
import com.commafeed.backend.model.UserRole.Role;
|
||||
import com.commafeed.backend.model.UserSettings;
|
||||
import com.commafeed.frontend.CommaFeedSession;
|
||||
import com.commafeed.frontend.SecurityCheck;
|
||||
import com.commafeed.frontend.references.UserCustomCssReference;
|
||||
import com.commafeed.frontend.references.angular.AngularReference;
|
||||
import com.commafeed.frontend.references.angular.AngularResourceReference;
|
||||
import com.commafeed.frontend.references.angular.AngularSanitizeReference;
|
||||
import com.commafeed.frontend.references.angularui.AngularUIReference;
|
||||
import com.commafeed.frontend.references.angularuibootstrap.AngularUIBootstrapReference;
|
||||
import com.commafeed.frontend.references.angularuistate.AngularUIStateReference;
|
||||
import com.commafeed.frontend.references.fontawesome.FontAwesomeReference;
|
||||
import com.commafeed.frontend.references.mousetrap.MouseTrapReference;
|
||||
import com.commafeed.frontend.references.nggrid.NGGridReference;
|
||||
import com.commafeed.frontend.references.nginfinitescroll.NGInfiniteScrollReference;
|
||||
import com.commafeed.frontend.references.ngupload.NGUploadReference;
|
||||
import com.commafeed.frontend.references.spinjs.SpinJSReference;
|
||||
import com.commafeed.frontend.resources.UserCustomCssReference;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@SecurityCheck(Role.USER)
|
||||
@@ -31,26 +18,6 @@ public class HomePage extends BasePage {
|
||||
public void renderHead(IHeaderResponse response) {
|
||||
super.renderHead(response);
|
||||
|
||||
AngularReference.renderHead(response);
|
||||
AngularResourceReference.renderHead(response);
|
||||
AngularSanitizeReference.renderHead(response);
|
||||
AngularUIReference.renderHead(response);
|
||||
AngularUIBootstrapReference.renderHead(response);
|
||||
AngularUIStateReference.renderHead(response);
|
||||
NGUploadReference.renderHead(response);
|
||||
NGInfiniteScrollReference.renderHead(response);
|
||||
SpinJSReference.renderHead(response);
|
||||
MouseTrapReference.renderHead(response);
|
||||
NGGridReference.renderHead(response);
|
||||
FontAwesomeReference.renderHead(response);
|
||||
|
||||
response.render(JavaScriptHeaderItem.forUrl("js/main.js"));
|
||||
response.render(JavaScriptHeaderItem.forUrl("js/controllers.js"));
|
||||
response.render(JavaScriptHeaderItem.forUrl("js/directives.js"));
|
||||
response.render(JavaScriptHeaderItem.forUrl("js/services.js"));
|
||||
|
||||
response.render(CssHeaderItem.forUrl("css/app.css"));
|
||||
|
||||
response.render(CssHeaderItem.forReference(
|
||||
new UserCustomCssReference() {
|
||||
@Override
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.header {
|
||||
margin: 20px 0 40px 0;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<html xmlns:wicket="http://wicket.apache.org">
|
||||
<body>
|
||||
<wicket:extend>
|
||||
<div class="container">
|
||||
<div class="container welcome">
|
||||
<div class="row header">
|
||||
<div class="text-center">
|
||||
<h1>
|
||||
|
||||
@@ -2,13 +2,11 @@ package com.commafeed.frontend.pages;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
|
||||
import com.commafeed.backend.services.ApplicationSettingsService;
|
||||
import com.commafeed.frontend.pages.components.LoginPanel;
|
||||
import com.commafeed.frontend.pages.components.RegisterPanel;
|
||||
import com.commafeed.frontend.utils.WicketUtils;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class WelcomePage extends BasePage {
|
||||
@@ -30,11 +28,4 @@ public class WelcomePage extends BasePage {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHead(IHeaderResponse response) {
|
||||
super.renderHead(response);
|
||||
WicketUtils.loadJS(response, WelcomePage.class);
|
||||
WicketUtils.loadCSS(response, WelcomePage.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
$(function() {
|
||||
var reg = $('#register-panel');
|
||||
if (!reg) {
|
||||
return;
|
||||
}
|
||||
$('#login-panel').height(reg.height());
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
.bs-fb ul {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
@@ -3,13 +3,9 @@ package com.commafeed.frontend.pages.components;
|
||||
import org.apache.wicket.behavior.AttributeAppender;
|
||||
import org.apache.wicket.feedback.IFeedbackMessageFilter;
|
||||
import org.apache.wicket.markup.ComponentTag;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.html.panel.FeedbackPanel;
|
||||
import org.apache.wicket.model.AbstractReadOnlyModel;
|
||||
|
||||
import com.commafeed.frontend.references.bootstrap.BootstrapReference;
|
||||
import com.commafeed.frontend.utils.WicketUtils;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class BootstrapFeedbackPanel extends FeedbackPanel {
|
||||
|
||||
@@ -50,12 +46,4 @@ public class BootstrapFeedbackPanel extends FeedbackPanel {
|
||||
tag.setName("div");
|
||||
super.onComponentTag(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHead(IHeaderResponse response) {
|
||||
super.renderHead(response);
|
||||
BootstrapReference.renderHead(response);
|
||||
WicketUtils.loadCSS(response, BootstrapFeedbackPanel.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.commafeed.frontend.references.angular;
|
||||
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.Url;
|
||||
import org.apache.wicket.request.resource.UrlResourceReference;
|
||||
|
||||
public class AngularReference extends UrlResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final AngularReference INSTANCE = new AngularReference();
|
||||
|
||||
private AngularReference() {
|
||||
super(
|
||||
Url.parse("https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.min.js"));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.commafeed.frontend.references.angular;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.Url;
|
||||
import org.apache.wicket.request.resource.UrlResourceReference;
|
||||
|
||||
public class AngularResourceReference extends UrlResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final AngularResourceReference INSTANCE = new AngularResourceReference();
|
||||
|
||||
private AngularResourceReference() {
|
||||
super(
|
||||
Url.parse("https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular-resource.min.js"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends HeaderItem> getDependencies() {
|
||||
return Arrays.asList(JavaScriptHeaderItem
|
||||
.forReference(AngularReference.INSTANCE));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.commafeed.frontend.references.angular;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.Url;
|
||||
import org.apache.wicket.request.resource.UrlResourceReference;
|
||||
|
||||
public class AngularSanitizeReference extends UrlResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final AngularSanitizeReference INSTANCE = new AngularSanitizeReference();
|
||||
|
||||
private AngularSanitizeReference() {
|
||||
super(
|
||||
Url.parse("https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular-sanitize.min.js"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends HeaderItem> getDependencies() {
|
||||
return Arrays.asList(JavaScriptHeaderItem
|
||||
.forReference(AngularReference.INSTANCE));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.commafeed.frontend.references.angularui;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.Url;
|
||||
import org.apache.wicket.request.resource.UrlResourceReference;
|
||||
|
||||
import com.commafeed.frontend.references.angular.AngularReference;
|
||||
|
||||
public class AngularUIReference extends UrlResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final AngularUIReference INSTANCE = new AngularUIReference();
|
||||
|
||||
private AngularUIReference() {
|
||||
super(
|
||||
Url.parse("https://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.min.js"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Iterable<? extends HeaderItem> getDependencies() {
|
||||
return Arrays
|
||||
.asList(JavaScriptHeaderItem
|
||||
.forReference(AngularReference.INSTANCE),
|
||||
CssHeaderItem.forReference(new UrlResourceReference(
|
||||
Url.parse("https://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.min.css"))));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.commafeed.frontend.references.angularuibootstrap;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.Url;
|
||||
import org.apache.wicket.request.resource.UrlResourceReference;
|
||||
|
||||
import com.commafeed.frontend.references.angular.AngularReference;
|
||||
|
||||
public class AngularUIBootstrapReference extends UrlResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final AngularUIBootstrapReference INSTANCE = new AngularUIBootstrapReference();
|
||||
|
||||
private AngularUIBootstrapReference() {
|
||||
super(Url.parse("https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.2.0/ui-bootstrap-tpls.js"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends HeaderItem> getDependencies() {
|
||||
return Arrays.asList(JavaScriptHeaderItem
|
||||
.forReference(AngularReference.INSTANCE));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.commafeed.frontend.references.angularuistate;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.resource.JavaScriptResourceReference;
|
||||
|
||||
import com.commafeed.frontend.references.angular.AngularReference;
|
||||
|
||||
public class AngularUIStateReference extends JavaScriptResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final AngularUIStateReference INSTANCE = new AngularUIStateReference();
|
||||
|
||||
private AngularUIStateReference() {
|
||||
super(AngularUIStateReference.class, "angular-ui-states.js");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends HeaderItem> getDependencies() {
|
||||
return Arrays.asList(JavaScriptHeaderItem
|
||||
.forReference(AngularReference.INSTANCE));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -1,995 +0,0 @@
|
||||
/*jshint globalstrict:true*/
|
||||
/*global angular:false*/
|
||||
'use strict';
|
||||
|
||||
var isDefined = angular.isDefined,
|
||||
isFunction = angular.isFunction,
|
||||
isString = angular.isString,
|
||||
isObject = angular.isObject,
|
||||
isArray = angular.isArray,
|
||||
forEach = angular.forEach,
|
||||
extend = angular.extend,
|
||||
copy = angular.copy;
|
||||
|
||||
function inherit(parent, extra) {
|
||||
return extend(new (extend(function() {}, { prototype: parent }))(), extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends the destination object `dst` by copying all of the properties from the `src` object(s)
|
||||
* to `dst` if the `dst` object has no own property of the same name. You can specify multiple
|
||||
* `src` objects.
|
||||
*
|
||||
* @param {Object} dst Destination object.
|
||||
* @param {...Object} src Source object(s).
|
||||
* @see angular.extend
|
||||
*/
|
||||
function merge(dst) {
|
||||
forEach(arguments, function(obj) {
|
||||
if (obj !== dst) {
|
||||
forEach(obj, function(value, key) {
|
||||
if (!dst.hasOwnProperty(key)) dst[key] = value;
|
||||
});
|
||||
}
|
||||
});
|
||||
return dst;
|
||||
}
|
||||
|
||||
angular.module('ui.util', ['ng']);
|
||||
angular.module('ui.router', ['ui.util']);
|
||||
angular.module('ui.state', ['ui.router', 'ui.util']);
|
||||
angular.module('ui.compat', ['ui.state']);
|
||||
|
||||
/**
|
||||
* Service. Manages loading of templates.
|
||||
* @constructor
|
||||
* @name $templateFactory
|
||||
* @requires $http
|
||||
* @requires $templateCache
|
||||
* @requires $injector
|
||||
*/
|
||||
$TemplateFactory.$inject = ['$http', '$templateCache', '$injector'];
|
||||
function $TemplateFactory( $http, $templateCache, $injector) {
|
||||
|
||||
/**
|
||||
* Creates a template from a configuration object.
|
||||
* @function
|
||||
* @name $templateFactory#fromConfig
|
||||
* @methodOf $templateFactory
|
||||
* @param {Object} config Configuration object for which to load a template. The following
|
||||
* properties are search in the specified order, and the first one that is defined is
|
||||
* used to create the template:
|
||||
* @param {string|Function} config.template html string template or function to load via
|
||||
* {@link $templateFactory#fromString fromString}.
|
||||
* @param {string|Function} config.templateUrl url to load or a function returning the url
|
||||
* to load via {@link $templateFactory#fromUrl fromUrl}.
|
||||
* @param {Function} config.templateProvider function to invoke via
|
||||
* {@link $templateFactory#fromProvider fromProvider}.
|
||||
* @param {Object} params Parameters to pass to the template function.
|
||||
* @param {Object} [locals] Locals to pass to `invoke` if the template is loaded via a
|
||||
* `templateProvider`. Defaults to `{ params: params }`.
|
||||
* @return {string|Promise.<string>} The template html as a string, or a promise for that string,
|
||||
* or `null` if no template is configured.
|
||||
*/
|
||||
this.fromConfig = function (config, params, locals) {
|
||||
return (
|
||||
isDefined(config.template) ? this.fromString(config.template, params) :
|
||||
isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :
|
||||
isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, locals) :
|
||||
null
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a template from a string or a function returning a string.
|
||||
* @function
|
||||
* @name $templateFactory#fromString
|
||||
* @methodOf $templateFactory
|
||||
* @param {string|Function} template html template as a string or function that returns an html
|
||||
* template as a string.
|
||||
* @param {Object} params Parameters to pass to the template function.
|
||||
* @return {string|Promise.<string>} The template html as a string, or a promise for that string.
|
||||
*/
|
||||
this.fromString = function (template, params) {
|
||||
return isFunction(template) ? template(params) : template;
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads a template from the a URL via `$http` and `$templateCache`.
|
||||
* @function
|
||||
* @name $templateFactory#fromUrl
|
||||
* @methodOf $templateFactory
|
||||
* @param {string|Function} url url of the template to load, or a function that returns a url.
|
||||
* @param {Object} params Parameters to pass to the url function.
|
||||
* @return {string|Promise.<string>} The template html as a string, or a promise for that string.
|
||||
*/
|
||||
this.fromUrl = function (url, params) {
|
||||
if (isFunction(url)) url = url(params);
|
||||
if (url == null) return null;
|
||||
else return $http
|
||||
.get(url, { cache: $templateCache })
|
||||
.then(function(response) { return response.data; });
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a template by invoking an injectable provider function.
|
||||
* @function
|
||||
* @name $templateFactory#fromUrl
|
||||
* @methodOf $templateFactory
|
||||
* @param {Function} provider Function to invoke via `$injector.invoke`
|
||||
* @param {Object} params Parameters for the template.
|
||||
* @param {Object} [locals] Locals to pass to `invoke`. Defaults to `{ params: params }`.
|
||||
* @return {string|Promise.<string>} The template html as a string, or a promise for that string.
|
||||
*/
|
||||
this.fromProvider = function (provider, params, locals) {
|
||||
return $injector.invoke(provider, null, locals || { params: params });
|
||||
};
|
||||
}
|
||||
|
||||
angular.module('ui.util').service('$templateFactory', $TemplateFactory);
|
||||
|
||||
/**
|
||||
* Matches URLs against patterns and extracts named parameters from the path or the search
|
||||
* part of the URL. A URL pattern consists of a path pattern, optionally followed by '?' and a list
|
||||
* of search parameters. Multiple search parameter names are separated by '&'. Search parameters
|
||||
* do not influence whether or not a URL is matched, but their values are passed through into
|
||||
* the matched parameters returned by {@link UrlMatcher#exec exec}.
|
||||
*
|
||||
* Path parameter placeholders can be specified using simple colon/catch-all syntax or curly brace
|
||||
* syntax, which optionally allows a regular expression for the parameter to be specified:
|
||||
*
|
||||
* * ':' name - colon placeholder
|
||||
* * '*' name - catch-all placeholder
|
||||
* * '{' name '}' - curly placeholder
|
||||
* * '{' name ':' regexp '}' - curly placeholder with regexp. Should the regexp itself contain
|
||||
* curly braces, they must be in matched pairs or escaped with a backslash.
|
||||
*
|
||||
* Parameter names may contain only word characters (latin letters, digits, and underscore) and
|
||||
* must be unique within the pattern (across both path and search parameters). For colon
|
||||
* placeholders or curly placeholders without an explicit regexp, a path parameter matches any
|
||||
* number of characters other than '/'. For catch-all placeholders the path parameter matches
|
||||
* any number of characters.
|
||||
*
|
||||
* ### Examples
|
||||
*
|
||||
* * '/hello/' - Matches only if the path is exactly '/hello/'. There is no special treatment for
|
||||
* trailing slashes, and patterns have to match the entire path, not just a prefix.
|
||||
* * '/user/:id' - Matches '/user/bob' or '/user/1234!!!' or even '/user/' but not '/user' or
|
||||
* '/user/bob/details'. The second path segment will be captured as the parameter 'id'.
|
||||
* * '/user/{id}' - Same as the previous example, but using curly brace syntax.
|
||||
* * '/user/{id:[^/]*}' - Same as the previous example.
|
||||
* * '/user/{id:[0-9a-fA-F]{1,8}}' - Similar to the previous example, but only matches if the id
|
||||
* parameter consists of 1 to 8 hex digits.
|
||||
* * '/files/{path:.*}' - Matches any URL starting with '/files/' and captures the rest of the
|
||||
* path into the parameter 'path'.
|
||||
* * '/files/*path' - ditto.
|
||||
*
|
||||
* @constructor
|
||||
* @param {string} pattern the pattern to compile into a matcher.
|
||||
*
|
||||
* @property {string} prefix A static prefix of this pattern. The matcher guarantees that any
|
||||
* URL matching this matcher (i.e. any string for which {@link UrlMatcher#exec exec()} returns
|
||||
* non-null) will start with this prefix.
|
||||
*/
|
||||
function UrlMatcher(pattern) {
|
||||
|
||||
// Find all placeholders and create a compiled pattern, using either classic or curly syntax:
|
||||
// '*' name
|
||||
// ':' name
|
||||
// '{' name '}'
|
||||
// '{' name ':' regexp '}'
|
||||
// The regular expression is somewhat complicated due to the need to allow curly braces
|
||||
// inside the regular expression. The placeholder regexp breaks down as follows:
|
||||
// ([:*])(\w+) classic placeholder ($1 / $2)
|
||||
// \{(\w+)(?:\:( ... ))?\} curly brace placeholder ($3) with optional regexp ... ($4)
|
||||
// (?: ... | ... | ... )+ the regexp consists of any number of atoms, an atom being either
|
||||
// [^{}\\]+ - anything other than curly braces or backslash
|
||||
// \\. - a backslash escape
|
||||
// \{(?:[^{}\\]+|\\.)*\} - a matched set of curly braces containing other atoms
|
||||
var placeholder = /([:*])(\w+)|\{(\w+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,
|
||||
names = {}, compiled = '^', last = 0, m,
|
||||
segments = this.segments = [],
|
||||
params = this.params = [];
|
||||
|
||||
function addParameter(id) {
|
||||
if (!/^\w+$/.test(id)) throw new Error("Invalid parameter name '" + id + "' in pattern '" + pattern + "'");
|
||||
if (names[id]) throw new Error("Duplicate parameter name '" + id + "' in pattern '" + pattern + "'");
|
||||
names[id] = true;
|
||||
params.push(id);
|
||||
}
|
||||
|
||||
function quoteRegExp(string) {
|
||||
return string.replace(/[\\\[\]\^$*+?.()|{}]/g, "\\$&");
|
||||
}
|
||||
|
||||
this.source = pattern;
|
||||
|
||||
// Split into static segments separated by path parameter placeholders.
|
||||
// The number of segments is always 1 more than the number of parameters.
|
||||
var id, regexp, segment;
|
||||
while ((m = placeholder.exec(pattern))) {
|
||||
id = m[2] || m[3]; // IE[78] returns '' for unmatched groups instead of null
|
||||
regexp = m[4] || (m[1] == '*' ? '.*' : '[^/]*');
|
||||
segment = pattern.substring(last, m.index);
|
||||
if (segment.indexOf('?') >= 0) break; // we're into the search part
|
||||
compiled += quoteRegExp(segment) + '(' + regexp + ')';
|
||||
addParameter(id);
|
||||
segments.push(segment);
|
||||
last = placeholder.lastIndex;
|
||||
}
|
||||
segment = pattern.substring(last);
|
||||
|
||||
// Find any search parameter names and remove them from the last segment
|
||||
var i = segment.indexOf('?');
|
||||
if (i >= 0) {
|
||||
var search = this.sourceSearch = segment.substring(i);
|
||||
segment = segment.substring(0, i);
|
||||
this.sourcePath = pattern.substring(0, last+i);
|
||||
|
||||
// Allow parameters to be separated by '?' as well as '&' to make concat() easier
|
||||
forEach(search.substring(1).split(/[&?]/), addParameter);
|
||||
} else {
|
||||
this.sourcePath = pattern;
|
||||
this.sourceSearch = '';
|
||||
}
|
||||
|
||||
compiled += quoteRegExp(segment) + '$';
|
||||
segments.push(segment);
|
||||
this.regexp = new RegExp(compiled);
|
||||
this.prefix = segments[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new matcher for a pattern constructed by appending the path part and adding the
|
||||
* search parameters of the specified pattern to this pattern. The current pattern is not
|
||||
* modified. This can be understood as creating a pattern for URLs that are relative to (or
|
||||
* suffixes of) the current pattern.
|
||||
*
|
||||
* ### Example
|
||||
* The following two matchers are equivalent:
|
||||
* ```
|
||||
* new UrlMatcher('/user/{id}?q').concat('/details?date');
|
||||
* new UrlMatcher('/user/{id}/details?q&date');
|
||||
* ```
|
||||
*
|
||||
* @param {string} pattern The pattern to append.
|
||||
* @return {UrlMatcher} A matcher for the concatenated pattern.
|
||||
*/
|
||||
UrlMatcher.prototype.concat = function (pattern) {
|
||||
// Because order of search parameters is irrelevant, we can add our own search
|
||||
// parameters to the end of the new pattern. Parse the new pattern by itself
|
||||
// and then join the bits together, but it's much easier to do this on a string level.
|
||||
return new UrlMatcher(this.sourcePath + pattern + this.sourceSearch);
|
||||
};
|
||||
|
||||
UrlMatcher.prototype.toString = function () {
|
||||
return this.source;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests the specified path against this matcher, and returns an object containing the captured
|
||||
* parameter values, or null if the path does not match. The returned object contains the values
|
||||
* of any search parameters that are mentioned in the pattern, but their value may be null if
|
||||
* they are not present in `searchParams`. This means that search parameters are always treated
|
||||
* as optional.
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* new UrlMatcher('/user/{id}?q&r').exec('/user/bob', { x:'1', q:'hello' });
|
||||
* // returns { id:'bob', q:'hello', r:null }
|
||||
* ```
|
||||
*
|
||||
* @param {string} path The URL path to match, e.g. `$location.path()`.
|
||||
* @param {Object} searchParams URL search parameters, e.g. `$location.search()`.
|
||||
* @return {Object} The captured parameter values.
|
||||
*/
|
||||
UrlMatcher.prototype.exec = function (path, searchParams) {
|
||||
var m = this.regexp.exec(path);
|
||||
if (!m) return null;
|
||||
|
||||
var params = this.params, nTotal = params.length,
|
||||
nPath = this.segments.length-1,
|
||||
values = {}, i;
|
||||
|
||||
for (i=0; i<nPath; i++) values[params[i]] = decodeURIComponent(m[i+1]);
|
||||
for (/**/; i<nTotal; i++) values[params[i]] = searchParams[params[i]];
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the names of all path and search parameters of this pattern in an unspecified order.
|
||||
* @return {Array.<string>} An array of parameter names. Must be treated as read-only. If the
|
||||
* pattern has no parameters, an empty array is returned.
|
||||
*/
|
||||
UrlMatcher.prototype.parameters = function () {
|
||||
return this.params;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a URL that matches this pattern by substituting the specified values
|
||||
* for the path and search parameters. Null values for path parameters are
|
||||
* treated as empty strings.
|
||||
*
|
||||
* ### Example
|
||||
* ```
|
||||
* new UrlMatcher('/user/{id}?q').format({ id:'bob', q:'yes' });
|
||||
* // returns '/user/bob?q=yes'
|
||||
* ```
|
||||
*
|
||||
* @param {Object} values the values to substitute for the parameters in this pattern.
|
||||
* @return {string} the formatted URL (path and optionally search part).
|
||||
*/
|
||||
UrlMatcher.prototype.format = function (values) {
|
||||
var segments = this.segments, params = this.params;
|
||||
if (!values) return segments.join('');
|
||||
|
||||
var nPath = segments.length-1, nTotal = params.length,
|
||||
result = segments[0], i, search, value;
|
||||
|
||||
for (i=0; i<nPath; i++) {
|
||||
value = values[params[i]];
|
||||
// TODO: Maybe we should throw on null here? It's not really good style to use '' and null interchangeabley
|
||||
if (value != null) result += value;
|
||||
result += segments[i+1];
|
||||
}
|
||||
for (/**/; i<nTotal; i++) {
|
||||
value = values[params[i]];
|
||||
if (value != null) {
|
||||
result += (search ? '&' : '?') + params[i] + '=' + encodeURIComponent(value);
|
||||
search = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Service. Factory for {@link UrlMatcher} instances. The factory is also available to providers
|
||||
* under the name `$urlMatcherFactoryProvider`.
|
||||
* @constructor
|
||||
* @name $urlMatcherFactory
|
||||
*/
|
||||
function $UrlMatcherFactory() {
|
||||
/**
|
||||
* Creates a {@link UrlMatcher} for the specified pattern.
|
||||
* @function
|
||||
* @name $urlMatcherFactory#compile
|
||||
* @methodOf $urlMatcherFactory
|
||||
* @param {string} pattern The URL pattern.
|
||||
* @return {UrlMatcher} The UrlMatcher.
|
||||
*/
|
||||
this.compile = function (pattern) {
|
||||
return new UrlMatcher(pattern);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the specified object is a UrlMatcher, or false otherwise.
|
||||
* @function
|
||||
* @name $urlMatcherFactory#isMatcher
|
||||
* @methodOf $urlMatcherFactory
|
||||
* @param {Object} o
|
||||
* @return {boolean}
|
||||
*/
|
||||
this.isMatcher = function (o) {
|
||||
return o instanceof UrlMatcher;
|
||||
};
|
||||
|
||||
this.$get = function () {
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
// Register as a provider so it's available to other providers
|
||||
angular.module('ui.util').provider('$urlMatcherFactory', $UrlMatcherFactory);
|
||||
|
||||
|
||||
$UrlRouterProvider.$inject = ['$urlMatcherFactoryProvider'];
|
||||
function $UrlRouterProvider( $urlMatcherFactory) {
|
||||
var rules = [], otherwise = null;
|
||||
|
||||
// Returns a string that is a prefix of all strings matching the RegExp
|
||||
function regExpPrefix(re) {
|
||||
var prefix = /^\^((?:\\[^a-zA-Z0-9]|[^\\\[\]\^$*+?.()|{}]+)*)/.exec(re.source);
|
||||
return (prefix != null) ? prefix[1].replace(/\\(.)/g, "$1") : '';
|
||||
}
|
||||
|
||||
// Interpolates matched values into a String.replace()-style pattern
|
||||
function interpolate(pattern, match) {
|
||||
return pattern.replace(/\$(\$|\d{1,2})/, function (m, what) {
|
||||
return match[what === '$' ? 0 : Number(what)];
|
||||
});
|
||||
}
|
||||
|
||||
this.rule =
|
||||
function (rule) {
|
||||
if (!isFunction(rule)) throw new Error("'rule' must be a function");
|
||||
rules.push(rule);
|
||||
return this;
|
||||
};
|
||||
|
||||
this.otherwise =
|
||||
function (rule) {
|
||||
if (isString(rule)) {
|
||||
var redirect = rule;
|
||||
rule = function () { return redirect; };
|
||||
}
|
||||
else if (!isFunction(rule)) throw new Error("'rule' must be a function");
|
||||
otherwise = rule;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
function handleIfMatch($location, handler, match) {
|
||||
if (!match) return false;
|
||||
var result = handler(match, $location);
|
||||
return isDefined(result) ? result : true;
|
||||
}
|
||||
|
||||
this.when =
|
||||
function (what, handler) {
|
||||
var rule, redirect;
|
||||
if (isString(what)) what = $urlMatcherFactory.compile(what);
|
||||
if ($urlMatcherFactory.isMatcher(what)) {
|
||||
if (isString(handler)) {
|
||||
redirect = $urlMatcherFactory.compile(handler);
|
||||
handler = function (match) { return redirect.format(match); };
|
||||
}
|
||||
else if (!isFunction(handler)) throw new Error("invalid 'handler' in when()");
|
||||
rule = function ($location) {
|
||||
return handleIfMatch($location, handler, what.exec($location.path(), $location.search()));
|
||||
};
|
||||
rule.prefix = isString(what.prefix) ? what.prefix : '';
|
||||
}
|
||||
else if (what instanceof RegExp) {
|
||||
if (isString(handler)) {
|
||||
redirect = handler;
|
||||
handler = function (match) { return interpolate(redirect, match); };
|
||||
}
|
||||
else if (!isFunction(handler)) throw new Error("invalid 'handler' in when()");
|
||||
if (what.global || what.sticky) throw new Error("when() RegExp must not be global or sticky");
|
||||
rule = function ($location) {
|
||||
return handleIfMatch($location, handler, what.exec($location.path()));
|
||||
};
|
||||
rule.prefix = regExpPrefix(what);
|
||||
}
|
||||
else throw new Error("invalid 'what' in when()");
|
||||
return this.rule(rule);
|
||||
};
|
||||
|
||||
this.$get =
|
||||
[ '$location', '$rootScope',
|
||||
function ($location, $rootScope) {
|
||||
if (otherwise) rules.push(otherwise);
|
||||
|
||||
// TODO: Optimize groups of rules with non-empty prefix into some sort of decision tree
|
||||
function update() {
|
||||
var n=rules.length, i, handled;
|
||||
for (i=0; i<n; i++) {
|
||||
handled = rules[i]($location);
|
||||
if (handled) {
|
||||
if (isString(handled)) $location.replace().url(handled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rootScope.$on('$locationChangeSuccess', update);
|
||||
return {};
|
||||
}];
|
||||
}
|
||||
|
||||
angular.module('ui.router').provider('$urlRouter', $UrlRouterProvider);
|
||||
|
||||
$StateProvider.$inject = ['$urlRouterProvider', '$urlMatcherFactoryProvider'];
|
||||
function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
|
||||
|
||||
var root, states = {}, $state;
|
||||
|
||||
function findState(stateOrName) {
|
||||
var state;
|
||||
if (isString(stateOrName)) {
|
||||
state = states[stateOrName];
|
||||
if (!state) throw new Error("No such state '" + stateOrName + "'");
|
||||
} else {
|
||||
state = states[stateOrName.name];
|
||||
if (!state || state !== stateOrName && state.self !== stateOrName)
|
||||
throw new Error("Invalid or unregistered state");
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
function registerState(state) {
|
||||
// Wrap a new object around the state so we can store our private details easily.
|
||||
state = inherit(state, {
|
||||
self: state,
|
||||
toString: function () { return this.name; }
|
||||
});
|
||||
|
||||
var name = state.name;
|
||||
if (!isString(name) || name.indexOf('@') >= 0) throw new Error("State must have a valid name");
|
||||
if (states[name]) throw new Error("State '" + name + "'' is already defined");
|
||||
|
||||
// Derive parent state from a hierarchical name only if 'parent' is not explicitly defined.
|
||||
var parent = root;
|
||||
if (!isDefined(state.parent)) {
|
||||
// regex matches any valid composite state name
|
||||
// would match "contact.list" but not "contacts"
|
||||
var compositeName = /^(.+)\.[^.]+$/.exec(name);
|
||||
if (compositeName != null) {
|
||||
parent = findState(compositeName[1]);
|
||||
}
|
||||
} else if (state.parent != null) {
|
||||
parent = findState(state.parent);
|
||||
}
|
||||
state.parent = parent;
|
||||
// state.children = [];
|
||||
// if (parent) parent.children.push(state);
|
||||
|
||||
// Build a URLMatcher if necessary, either via a relative or absolute URL
|
||||
var url = state.url;
|
||||
if (isString(url)) {
|
||||
if (url.charAt(0) == '^') {
|
||||
url = state.url = $urlMatcherFactory.compile(url.substring(1));
|
||||
} else {
|
||||
url = state.url = (parent.navigable || root).url.concat(url);
|
||||
}
|
||||
} else if (isObject(url) &&
|
||||
isFunction(url.exec) && isFunction(url.format) && isFunction(url.concat)) {
|
||||
/* use UrlMatcher (or compatible object) as is */
|
||||
} else if (url != null) {
|
||||
throw new Error("Invalid url '" + url + "' in state '" + state + "'");
|
||||
}
|
||||
|
||||
// Keep track of the closest ancestor state that has a URL (i.e. is navigable)
|
||||
state.navigable = url ? state : parent ? parent.navigable : null;
|
||||
|
||||
// Derive parameters for this state and ensure they're a super-set of parent's parameters
|
||||
var params = state.params;
|
||||
if (params) {
|
||||
if (!isArray(params)) throw new Error("Invalid params in state '" + state + "'");
|
||||
if (url) throw new Error("Both params and url specicified in state '" + state + "'");
|
||||
} else {
|
||||
params = state.params = url ? url.parameters() : state.parent.params;
|
||||
}
|
||||
|
||||
var paramNames = {}; forEach(params, function (p) { paramNames[p] = true; });
|
||||
if (parent) {
|
||||
forEach(parent.params, function (p) {
|
||||
if (!paramNames[p]) {
|
||||
throw new Error("Missing required parameter '" + p + "' in state '" + name + "'");
|
||||
}
|
||||
paramNames[p] = false;
|
||||
});
|
||||
|
||||
var ownParams = state.ownParams = [];
|
||||
forEach(paramNames, function (own, p) {
|
||||
if (own) ownParams.push(p);
|
||||
});
|
||||
} else {
|
||||
state.ownParams = params;
|
||||
}
|
||||
|
||||
// If there is no explicit multi-view configuration, make one up so we don't have
|
||||
// to handle both cases in the view directive later. Note that having an explicit
|
||||
// 'views' property will mean the default unnamed view properties are ignored. This
|
||||
// is also a good time to resolve view names to absolute names, so everything is a
|
||||
// straight lookup at link time.
|
||||
var views = {};
|
||||
forEach(isDefined(state.views) ? state.views : { '': state }, function (view, name) {
|
||||
if (name.indexOf('@') < 0) name = name + '@' + state.parent.name;
|
||||
views[name] = view;
|
||||
});
|
||||
state.views = views;
|
||||
|
||||
// Keep a full path from the root down to this state as this is needed for state activation.
|
||||
state.path = parent ? parent.path.concat(state) : []; // exclude root from path
|
||||
|
||||
// Speed up $state.contains() as it's used a lot
|
||||
var includes = state.includes = parent ? extend({}, parent.includes) : {};
|
||||
includes[name] = true;
|
||||
|
||||
if (!state.resolve) state.resolve = {}; // prevent null checks later
|
||||
|
||||
// Register the state in the global state list and with $urlRouter if necessary.
|
||||
if (!state.abstract && url) {
|
||||
$urlRouterProvider.when(url, function (params) {
|
||||
$state.transitionTo(state, params, false);
|
||||
});
|
||||
}
|
||||
states[name] = state;
|
||||
return state;
|
||||
}
|
||||
|
||||
// Implicit root state that is always active
|
||||
root = registerState({
|
||||
name: '',
|
||||
url: '^',
|
||||
views: null,
|
||||
abstract: true
|
||||
});
|
||||
root.locals = { globals: { $stateParams: {} } };
|
||||
root.navigable = null;
|
||||
|
||||
|
||||
// .state(state)
|
||||
// .state(name, state)
|
||||
this.state = state;
|
||||
function state(name, definition) {
|
||||
/*jshint validthis: true */
|
||||
if (isObject(name)) definition = name;
|
||||
else definition.name = name;
|
||||
registerState(definition);
|
||||
return this;
|
||||
}
|
||||
|
||||
// $urlRouter is injected just to ensure it gets instantiated
|
||||
this.$get = $get;
|
||||
$get.$inject = ['$rootScope', '$q', '$templateFactory', '$injector', '$stateParams', '$location', '$urlRouter'];
|
||||
function $get( $rootScope, $q, $templateFactory, $injector, $stateParams, $location, $urlRouter) {
|
||||
|
||||
var TransitionSuperseded = $q.reject(new Error('transition superseded'));
|
||||
var TransitionPrevented = $q.reject(new Error('transition prevented'));
|
||||
|
||||
$state = {
|
||||
params: {},
|
||||
current: root.self,
|
||||
$current: root,
|
||||
transition: null
|
||||
};
|
||||
|
||||
// $state.go = function go(to, params) {
|
||||
// };
|
||||
|
||||
$state.transitionTo = function transitionTo(to, toParams, updateLocation) {
|
||||
if (!isDefined(updateLocation)) updateLocation = true;
|
||||
|
||||
to = findState(to);
|
||||
if (to.abstract) throw new Error("Cannot transition to abstract state '" + to + "'");
|
||||
var toPath = to.path,
|
||||
from = $state.$current, fromParams = $state.params, fromPath = from.path;
|
||||
|
||||
// Starting from the root of the path, keep all levels that haven't changed
|
||||
var keep, state, locals = root.locals, toLocals = [];
|
||||
for (keep = 0, state = toPath[keep];
|
||||
state && state === fromPath[keep] && equalForKeys(toParams, fromParams, state.ownParams);
|
||||
keep++, state = toPath[keep]) {
|
||||
locals = toLocals[keep] = state.locals;
|
||||
}
|
||||
|
||||
// If we're going to the same state and all locals are kept, we've got nothing to do.
|
||||
// But clear 'transition', as we still want to cancel any other pending transitions.
|
||||
// TODO: We may not want to bump 'transition' if we're called from a location change that we've initiated ourselves,
|
||||
// because we might accidentally abort a legitimate transition initiated from code?
|
||||
if (to === from && locals === from.locals) {
|
||||
$state.transition = null;
|
||||
return $q.when($state.current);
|
||||
}
|
||||
|
||||
// Normalize/filter parameters before we pass them to event handlers etc.
|
||||
var normalizedToParams = {};
|
||||
forEach(to.params, function (name) {
|
||||
var value = toParams[name];
|
||||
normalizedToParams[name] = (value != null) ? String(value) : null;
|
||||
});
|
||||
toParams = normalizedToParams;
|
||||
|
||||
// Broadcast start event and cancel the transition if requested
|
||||
if ($rootScope.$broadcast('$stateChangeStart', to.self, toParams, from.self, fromParams)
|
||||
.defaultPrevented) return TransitionPrevented;
|
||||
|
||||
// Resolve locals for the remaining states, but don't update any global state just
|
||||
// yet -- if anything fails to resolve the current state needs to remain untouched.
|
||||
// We also set up an inheritance chain for the locals here. This allows the view directive
|
||||
// to quickly look up the correct definition for each view in the current state. Even
|
||||
// though we create the locals object itself outside resolveState(), it is initially
|
||||
// empty and gets filled asynchronously. We need to keep track of the promise for the
|
||||
// (fully resolved) current locals, and pass this down the chain.
|
||||
var resolved = $q.when(locals);
|
||||
for (var l=keep; l<toPath.length; l++, state=toPath[l]) {
|
||||
locals = toLocals[l] = inherit(locals);
|
||||
resolved = resolveState(state, toParams, state===to, resolved, locals);
|
||||
}
|
||||
|
||||
// Once everything is resolved, we are ready to perform the actual transition
|
||||
// and return a promise for the new state. We also keep track of what the
|
||||
// current promise is, so that we can detect overlapping transitions and
|
||||
// keep only the outcome of the last transition.
|
||||
var transition = $state.transition = resolved.then(function () {
|
||||
var l, entering, exiting;
|
||||
|
||||
if ($state.transition !== transition) return TransitionSuperseded;
|
||||
|
||||
// Exit 'from' states not kept
|
||||
for (l=fromPath.length-1; l>=keep; l--) {
|
||||
exiting = fromPath[l];
|
||||
if (exiting.self.onExit) {
|
||||
$injector.invoke(exiting.self.onExit, exiting.self, exiting.locals.globals);
|
||||
}
|
||||
exiting.locals = null;
|
||||
}
|
||||
|
||||
// Enter 'to' states not kept
|
||||
for (l=keep; l<toPath.length; l++) {
|
||||
entering = toPath[l];
|
||||
entering.locals = toLocals[l];
|
||||
if (entering.self.onEnter) {
|
||||
$injector.invoke(entering.self.onEnter, entering.self, entering.locals.globals);
|
||||
}
|
||||
}
|
||||
|
||||
// Update globals in $state
|
||||
$state.$current = to;
|
||||
$state.current = to.self;
|
||||
$state.params = toParams;
|
||||
copy($state.params, $stateParams);
|
||||
$state.transition = null;
|
||||
|
||||
// Update $location
|
||||
var toNav = to.navigable;
|
||||
if (updateLocation && toNav) {
|
||||
$location.url(toNav.url.format(toNav.locals.globals.$stateParams));
|
||||
}
|
||||
|
||||
$rootScope.$broadcast('$stateChangeSuccess', to.self, toParams, from.self, fromParams);
|
||||
|
||||
return $state.current;
|
||||
}, function (error) {
|
||||
if ($state.transition !== transition) return TransitionSuperseded;
|
||||
|
||||
$state.transition = null;
|
||||
$rootScope.$broadcast('$stateChangeError', to.self, toParams, from.self, fromParams, error);
|
||||
|
||||
return $q.reject(error);
|
||||
});
|
||||
|
||||
return transition;
|
||||
};
|
||||
|
||||
$state.is = function (stateOrName) {
|
||||
return $state.$current === findState(stateOrName);
|
||||
};
|
||||
|
||||
$state.includes = function (stateOrName) {
|
||||
return $state.$current.includes[findState(stateOrName).name];
|
||||
};
|
||||
|
||||
|
||||
function resolveState(state, params, paramsAreFiltered, inherited, dst) {
|
||||
// We need to track all the promises generated during the resolution process.
|
||||
// The first of these is for the fully resolved parent locals.
|
||||
var promises = [inherited];
|
||||
|
||||
// Make a restricted $stateParams with only the parameters that apply to this state if
|
||||
// necessary. In addition to being available to the controller and onEnter/onExit callbacks,
|
||||
// we also need $stateParams to be available for any $injector calls we make during the
|
||||
// dependency resolution process.
|
||||
var $stateParams;
|
||||
if (paramsAreFiltered) $stateParams = params;
|
||||
else {
|
||||
$stateParams = {};
|
||||
forEach(state.params, function (name) {
|
||||
$stateParams[name] = params[name];
|
||||
});
|
||||
}
|
||||
var locals = { $stateParams: $stateParams };
|
||||
|
||||
// Resolves the values from an individual 'resolve' dependency spec
|
||||
function resolve(deps, dst) {
|
||||
forEach(deps, function (value, key) {
|
||||
promises.push($q
|
||||
.when(isString(value) ?
|
||||
$injector.get(value) :
|
||||
$injector.invoke(value, state.self, locals))
|
||||
.then(function (result) {
|
||||
dst[key] = result;
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
// Resolve 'global' dependencies for the state, i.e. those not specific to a view.
|
||||
// We're also including $stateParams in this; that we're the parameters are restricted
|
||||
// to the set that should be visible to the state, and are independent of when we update
|
||||
// the global $state and $stateParams values.
|
||||
var globals = dst.globals = { $stateParams: $stateParams };
|
||||
resolve(state.resolve, globals);
|
||||
globals.$$state = state; // Provide access to the state itself for internal use
|
||||
|
||||
// Resolve template and dependencies for all views.
|
||||
forEach(state.views, function (view, name) {
|
||||
// References to the controller (only instantiated at link time)
|
||||
var $view = dst[name] = {
|
||||
$$controller: view.controller
|
||||
};
|
||||
|
||||
// Template
|
||||
promises.push($q
|
||||
.when($templateFactory.fromConfig(view, $stateParams, locals) || '')
|
||||
.then(function (result) {
|
||||
$view.$template = result;
|
||||
}));
|
||||
|
||||
// View-local dependencies. If we've reused the state definition as the default
|
||||
// view definition in .state(), we can end up with state.resolve === view.resolve.
|
||||
// Avoid resolving everything twice in that case.
|
||||
if (view.resolve !== state.resolve) resolve(view.resolve, $view);
|
||||
});
|
||||
|
||||
// Once we've resolved all the dependencies for this state, merge
|
||||
// in any inherited dependencies, and merge common state dependencies
|
||||
// into the dependency set for each view. Finally return a promise
|
||||
// for the fully popuplated state dependencies.
|
||||
return $q.all(promises).then(function (values) {
|
||||
merge(dst.globals, values[0].globals); // promises[0] === inherited
|
||||
forEach(state.views, function (view, name) {
|
||||
merge(dst[name], dst.globals);
|
||||
});
|
||||
return dst;
|
||||
});
|
||||
}
|
||||
|
||||
function equalForKeys(a, b, keys) {
|
||||
for (var i=0; i<keys.length; i++) {
|
||||
var k = keys[i];
|
||||
if (a[k] != b[k]) return false; // Not '===', values aren't necessarily normalized
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
}
|
||||
|
||||
angular.module('ui.state')
|
||||
.value('$stateParams', {})
|
||||
.provider('$state', $StateProvider);
|
||||
|
||||
|
||||
$ViewDirective.$inject = ['$state', '$compile', '$controller', '$anchorScroll'];
|
||||
function $ViewDirective( $state, $compile, $controller, $anchorScroll) {
|
||||
var directive = {
|
||||
restrict: 'ECA',
|
||||
terminal: true,
|
||||
link: function(scope, element, attr) {
|
||||
var viewScope, viewLocals,
|
||||
name = attr[directive.name] || attr.name || '',
|
||||
onloadExp = attr.onload || '';
|
||||
|
||||
// Find the details of the parent view directive (if any) and use it
|
||||
// to derive our own qualified view name, then hang our own details
|
||||
// off the DOM so child directives can find it.
|
||||
var parent = element.parent().inheritedData('$uiView');
|
||||
if (name.indexOf('@') < 0) name = name + '@' + (parent ? parent.state.name : '');
|
||||
var view = { name: name, state: null };
|
||||
element.data('$uiView', view);
|
||||
|
||||
scope.$on('$stateChangeSuccess', updateView);
|
||||
updateView();
|
||||
|
||||
function updateView() {
|
||||
var locals = $state.$current && $state.$current.locals[name];
|
||||
if (locals === viewLocals) return; // nothing to do
|
||||
|
||||
// Destroy previous view scope (if any)
|
||||
if (viewScope) {
|
||||
viewScope.$destroy();
|
||||
viewScope = null;
|
||||
}
|
||||
|
||||
if (locals) {
|
||||
viewLocals = locals;
|
||||
view.state = locals.$$state;
|
||||
|
||||
element.html(locals.$template);
|
||||
// element.html('<div style="height:0;position:relative;z-index:999"><span style="background:red;color:white;font-size:12px;padding:1px">' + name + '</span></div>' + locals.$template);
|
||||
var link = $compile(element.contents());
|
||||
viewScope = scope.$new();
|
||||
if (locals.$$controller) {
|
||||
locals.$scope = viewScope;
|
||||
var controller = $controller(locals.$$controller, locals);
|
||||
element.contents().data('$ngControllerController', controller);
|
||||
}
|
||||
link(viewScope);
|
||||
viewScope.$emit('$viewContentLoaded');
|
||||
viewScope.$eval(onloadExp);
|
||||
|
||||
// TODO: This seems strange, shouldn't $anchorScroll listen for $viewContentLoaded if necessary?
|
||||
// $anchorScroll might listen on event...
|
||||
$anchorScroll();
|
||||
} else {
|
||||
viewLocals = null;
|
||||
view.state = null;
|
||||
element.html('');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return directive;
|
||||
}
|
||||
|
||||
angular.module('ui.state').directive('uiView', $ViewDirective);
|
||||
|
||||
$RouteProvider.$inject = ['$stateProvider', '$urlRouterProvider'];
|
||||
function $RouteProvider( $stateProvider, $urlRouterProvider) {
|
||||
|
||||
var routes = [];
|
||||
|
||||
onEnterRoute.$inject = ['$$state'];
|
||||
function onEnterRoute( $$state) {
|
||||
/*jshint validthis: true */
|
||||
this.locals = $$state.locals.globals;
|
||||
this.params = this.locals.$stateParams;
|
||||
}
|
||||
|
||||
function onExitRoute() {
|
||||
/*jshint validthis: true */
|
||||
this.locals = null;
|
||||
this.params = null;
|
||||
}
|
||||
|
||||
this.when = when;
|
||||
function when(url, route) {
|
||||
/*jshint validthis: true */
|
||||
if (route.redirectTo != null) {
|
||||
// Redirect, configure directly on $urlRouterProvider
|
||||
var redirect = route.redirectTo, handler;
|
||||
if (isString(redirect)) {
|
||||
handler = redirect; // leave $urlRouterProvider to handle
|
||||
} else if (isFunction(redirect)) {
|
||||
// Adapt to $urlRouterProvider API
|
||||
handler = function (params, $location) {
|
||||
return redirect(params, $location.path(), $location.search());
|
||||
};
|
||||
} else {
|
||||
throw new Error("Invalid 'redirectTo' in when()");
|
||||
}
|
||||
$urlRouterProvider.when(url, handler);
|
||||
} else {
|
||||
// Regular route, configure as state
|
||||
$stateProvider.state(inherit(route, {
|
||||
parent: null,
|
||||
name: 'route:' + encodeURIComponent(url),
|
||||
url: url,
|
||||
onEnter: onEnterRoute,
|
||||
onExit: onExitRoute
|
||||
}));
|
||||
}
|
||||
routes.push(route);
|
||||
return this;
|
||||
}
|
||||
|
||||
this.$get = $get;
|
||||
$get.$inject = ['$state', '$rootScope', '$routeParams'];
|
||||
function $get( $state, $rootScope, $routeParams) {
|
||||
|
||||
var $route = {
|
||||
routes: routes,
|
||||
params: $routeParams,
|
||||
current: undefined
|
||||
};
|
||||
|
||||
function stateAsRoute(state) {
|
||||
return (state.name !== '') ? state : undefined;
|
||||
}
|
||||
|
||||
$rootScope.$on('$stateChangeStart', function (ev, to, toParams, from, fromParams) {
|
||||
$rootScope.$broadcast('$routeChangeStart', stateAsRoute(to), stateAsRoute(from));
|
||||
});
|
||||
|
||||
$rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
|
||||
$route.current = stateAsRoute(to);
|
||||
$rootScope.$broadcast('$routeChangeSuccess', stateAsRoute(to), stateAsRoute(from));
|
||||
copy(toParams, $route.params);
|
||||
});
|
||||
|
||||
$rootScope.$on('$stateChangeError', function (ev, to, toParams, from, fromParams, error) {
|
||||
$rootScope.$broadcast('$routeChangeError', stateAsRoute(to), stateAsRoute(from), error);
|
||||
});
|
||||
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
|
||||
angular.module('ui.compat')
|
||||
.provider('$route', $RouteProvider)
|
||||
.directive('ngView', $ViewDirective);
|
||||
File diff suppressed because one or more lines are too long
@@ -1,41 +0,0 @@
|
||||
package com.commafeed.frontend.references.bootstrap;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.Url;
|
||||
import org.apache.wicket.request.resource.UrlResourceReference;
|
||||
|
||||
import com.commafeed.frontend.references.jquery.JQueryReference;
|
||||
|
||||
public class BootstrapReference extends UrlResourceReference {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final BootstrapReference INSTANCE = new BootstrapReference();
|
||||
|
||||
public BootstrapReference() {
|
||||
super(
|
||||
Url.parse("https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.0/bootstrap.min.js"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Iterable<? extends HeaderItem> getDependencies() {
|
||||
return Arrays
|
||||
.asList(JavaScriptHeaderItem
|
||||
.forReference(JQueryReference.INSTANCE),
|
||||
CssHeaderItem.forReference(new UrlResourceReference(
|
||||
Url.parse("https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.0/css/bootstrap.no-icons.min.css"))),
|
||||
CssHeaderItem.forReference(new UrlResourceReference(
|
||||
Url.parse("https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.0/css/bootstrap-responsive.min.css"))));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.commafeed.frontend.references.fontawesome;
|
||||
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.request.Url;
|
||||
import org.apache.wicket.request.resource.UrlResourceReference;
|
||||
|
||||
public class FontAwesomeReference extends UrlResourceReference {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final FontAwesomeReference INSTANCE = new FontAwesomeReference();
|
||||
|
||||
public FontAwesomeReference() {
|
||||
super(
|
||||
Url.parse("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/3.0.2/css/font-awesome.min.css"));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(CssHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.commafeed.frontend.references.jquery;
|
||||
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.Url;
|
||||
import org.apache.wicket.request.resource.UrlResourceReference;
|
||||
|
||||
public class JQueryReference extends UrlResourceReference {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final JQueryReference INSTANCE = new JQueryReference();
|
||||
|
||||
public JQueryReference() {
|
||||
super(
|
||||
Url.parse("https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.commafeed.frontend.references.mousetrap;
|
||||
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.Url;
|
||||
import org.apache.wicket.request.resource.UrlResourceReference;
|
||||
|
||||
public class MouseTrapReference extends UrlResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final MouseTrapReference INSTANCE = new MouseTrapReference();
|
||||
|
||||
private MouseTrapReference() {
|
||||
super(
|
||||
Url.parse("https://cdnjs.cloudflare.com/ajax/libs/mousetrap/1.2.2/mousetrap.min.js"));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.commafeed.frontend.references.nggrid;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.resource.CssResourceReference;
|
||||
import org.apache.wicket.request.resource.JavaScriptResourceReference;
|
||||
|
||||
import com.commafeed.frontend.references.angular.AngularReference;
|
||||
|
||||
public class NGGridReference extends JavaScriptResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final NGGridReference INSTANCE = new NGGridReference();
|
||||
|
||||
private NGGridReference() {
|
||||
super(NGGridReference.class, "ng-grid-2.0.2.js");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Iterable<? extends HeaderItem> getDependencies() {
|
||||
return Arrays.asList(JavaScriptHeaderItem
|
||||
.forReference(AngularReference.INSTANCE), CssHeaderItem
|
||||
.forReference(new CssResourceReference(NGGridReference.class,
|
||||
"ng-grid.css")));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,472 +0,0 @@
|
||||
|
||||
/******** Grid Global ********/
|
||||
.nglabel {
|
||||
display: block;
|
||||
float: left;
|
||||
font-weight: bold;
|
||||
padding-right: 5px;
|
||||
}
|
||||
/******** Grid ********/
|
||||
|
||||
.ngGrid{
|
||||
background-color: rgb(253, 253, 253);
|
||||
}
|
||||
|
||||
/******** Header ********/
|
||||
|
||||
.ngGroupPanel{
|
||||
background-color: rgb(234, 234, 234);
|
||||
overflow: hidden;
|
||||
border-bottom: 1px solid rgb(212,212,212);
|
||||
}
|
||||
|
||||
.ngGroupPanelDescription{
|
||||
margin-top: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.ngGroupList {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ngGroupItem {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ngGroupElement {
|
||||
float: left;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ngGroupName {
|
||||
background-color: rgb(247,247,247);
|
||||
border: 1px solid rgb(212,212,212);
|
||||
padding: 3px 10px;
|
||||
float: left;
|
||||
margin-left: 0;
|
||||
margin-top: 2px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.ngGroupItem:first-child{
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.ngRemoveGroup {
|
||||
width: 5px;
|
||||
-moz-opacity: 0.4;
|
||||
opacity: 0.4;
|
||||
margin-top: -1px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.ngRemoveGroup:hover {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
-moz-opacity: 0.7;
|
||||
opacity: 0.7;
|
||||
}
|
||||
.ngGroupArrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
border-left: 6px solid black;
|
||||
margin-top: 10px;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.ngTopPanel {
|
||||
position: relative;
|
||||
z-index:5;
|
||||
background-color: rgb(234, 234, 234);
|
||||
border-bottom: 1px solid rgb(212,212,212);
|
||||
}
|
||||
.ngHeaderContainer {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
font-weight: bold;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.ngHeaderScroller {
|
||||
position:absolute;
|
||||
background-color: inherit;
|
||||
}
|
||||
.ngHeaderSortColumn{
|
||||
position:absolute;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ngHeaderCell{
|
||||
border-right: 1px solid rgb(212,212,212);
|
||||
border-left: 1px solid rgb(212,212,212);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.ngHeaderCell:first-child{
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.ngSortButtonUp {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border-color: gray transparent;
|
||||
border-style: solid;
|
||||
border-width: 0 5px 5px 5px;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
.ngSortButtonDown {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border-color: gray transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px 5px 0 5px;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
.ngSortPriority {
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
left: 1px;
|
||||
font-size: 6pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
.ngHeaderGrip {
|
||||
cursor: col-resize;
|
||||
width: 10px;
|
||||
right: -5px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background-color: transparent;
|
||||
}
|
||||
.ngHeaderText {
|
||||
padding: 5px;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
-ms-text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/******** Viewport ********/
|
||||
.ngViewport{
|
||||
overflow: auto;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
.ngCanvas{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/******** Rows ********/
|
||||
.ngRow {
|
||||
position: absolute;
|
||||
border-bottom: 1px solid rgb(229, 229, 229);
|
||||
}
|
||||
.ngRow.even {
|
||||
background-color: rgb(243, 243, 243);
|
||||
}
|
||||
.ngRow.odd {
|
||||
background-color: rgb(253, 253, 253);
|
||||
}
|
||||
.ngRow.selected {
|
||||
background-color: rgb(201, 221, 225);
|
||||
}
|
||||
.ngRow.canSelect {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/******** Cells ********/
|
||||
|
||||
.ngCell {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
border-right: 1px solid rgb(212,212,212);
|
||||
border-left: 1px solid rgb(212,212,212);
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.ngCell:first-child{
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.ngCellElement:focus {
|
||||
outline: 0;
|
||||
background-color: rgb(179, 196, 199);
|
||||
}
|
||||
|
||||
.ngCellText {
|
||||
padding: 5px;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
-ms-text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ngSelectionHeader {
|
||||
position: absolute;
|
||||
top: 11px;
|
||||
left: 6px;
|
||||
}
|
||||
.ngGrid input[type="checkbox"] {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.ngGrid input {
|
||||
vertical-align:top;
|
||||
}
|
||||
.ngSelectionCell{
|
||||
margin-top: 9px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
.ngSelectionCheckbox{
|
||||
margin-top: 9px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
.ngNoSort {
|
||||
cursor:default;
|
||||
}
|
||||
|
||||
/******** Footer ********/
|
||||
.ngFooterPanel{
|
||||
background-color: rgb(234, 234, 234);
|
||||
padding: 0;
|
||||
border-top: 1px solid rgb(212,212,212);
|
||||
position: relative;
|
||||
}
|
||||
.ngTotalSelectContainer {
|
||||
float: left;
|
||||
margin: 5px;
|
||||
margin-top: 7px;
|
||||
}
|
||||
.ngFooterSelectedItems {
|
||||
padding: 2px;
|
||||
}
|
||||
.ngFooterTotalItems {
|
||||
padding: 2px;
|
||||
}
|
||||
.ngFooterTotalItems.ngnoMultiSelect {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Aggregates */
|
||||
.ngAggHeader {
|
||||
position: absolute;
|
||||
border: none;
|
||||
}
|
||||
.ngAggregate {
|
||||
position: absolute;
|
||||
background-color: rgb(201, 221, 225);
|
||||
border-bottom: 1px solid beige;
|
||||
overflow: hidden;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: -1px;
|
||||
left: 0;
|
||||
}
|
||||
.ngAggregateText {
|
||||
position: absolute;
|
||||
left: 27px;
|
||||
top: 5px;
|
||||
line-height: 20px;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.ngAggArrowExpanded {
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
bottom: 10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 0 0 9px 9px;
|
||||
border-color: transparent transparent #000000 transparent;
|
||||
}
|
||||
.ngAggArrowCollapsed {
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
bottom: 10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 5px 0 5px 8.7px;
|
||||
border-color: transparent transparent transparent #000000;
|
||||
}
|
||||
|
||||
.ngHeaderButton {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
top: 8px;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
z-index: 5;
|
||||
background-color: rgb(179, 191, 188);
|
||||
cursor: pointer;
|
||||
/* width and height can be anything, as long as they're equal */
|
||||
}
|
||||
.ngHeaderButtonArrow {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 3px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 6.5px 4.5px 0 4.5px;
|
||||
border-color: #000 transparent transparent transparent;
|
||||
/* width and height can be anything, as long as they're equal */
|
||||
}
|
||||
.ngColMenu {
|
||||
right: 2px;
|
||||
padding: 5px;
|
||||
top: 25px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
background-color: #BDD0CB;
|
||||
position: absolute;
|
||||
border: 2px solid rgb(212,212,212);
|
||||
z-index: 5;
|
||||
}
|
||||
.ngMenuText {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
}
|
||||
.ngColList {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.ngColListItem {
|
||||
position: relative;
|
||||
right: 17px;
|
||||
top: 2px;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.ngColListCheckbox {
|
||||
position: relative;
|
||||
right: 3px;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
/********Paging Styles **********/
|
||||
|
||||
.ngPagerButton{
|
||||
height: 25px;
|
||||
min-width: 26px;
|
||||
}
|
||||
|
||||
.ngPagerFirstTriangle{
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 5px 8.7px 5px 0;
|
||||
border-color: transparent #000000 transparent transparent;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.ngPagerFirstBar{
|
||||
width: 10px;
|
||||
border-left: 2px solid black;
|
||||
margin-top: -6px;
|
||||
height: 12px;
|
||||
margin-left: -3px;
|
||||
}
|
||||
|
||||
.ngPagerLastTriangle{
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 5px 0 5px 8.7px;
|
||||
border-color: transparent transparent transparent #000000;
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
.ngPagerLastBar{
|
||||
width: 10px;
|
||||
border-left: 2px solid black;
|
||||
margin-top: -6px;
|
||||
height: 12px;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.ngPagerPrevTriangle{
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.ngPagerNextTriangle{
|
||||
margin-left: 1px;
|
||||
}
|
||||
.ngGroupIcon {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAYAAACZ3F9/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAEFJREFUKFNjoAhISkr+h2J5JDZODNXGwGBsbPwfhIGAA8bGh6HaGBiAGhxAGJmND4M1gQCSM0adCsVQbcPcqQwMALWDGyDvWPefAAAAAElFTkSuQmCC);
|
||||
background-repeat:no-repeat;
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.ngGroupedByIcon {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAYAAACZ3F9/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAElJREFUKFNjoAhISkr+R8LyaHwMDNXGwGBsbPwfhoGAA5mPDUO1oWpE52PDYE0gALTFAYbR+dgwWBMIoPlh1I9ADNU2NPzIwAAAFQYI9E4OLvEAAAAASUVORK5CYII=);
|
||||
background-repeat:no-repeat;
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
top: 2px;
|
||||
}
|
||||
.ngPinnedIcon {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAmElEQVQoU33PQapBURjA8UtkwJuaWYGSgfQWYBMvczPmTCzAAGVuaA228BZhRCkDGSmE31FucuRfvzq3vr5zT/JSjSU7DsypEPXDkDVn2hSIytJhw4kWGaLCxgHh2gt/RBuLzNhz5caWPjnSqqw4EraFfwznf8qklWjwy4IRTerkiQoPGtPl40OehcEJvcfXl8LglLfBJLkDcMgbgHlHhK8AAAAASUVORK5CYII=);
|
||||
background-repeat: no-repeat;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
.ngUnPinnedIcon {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAlElEQVQoU33PPQrCQBRF4fFnI2KfZVi5ARvdgo1l6mwmkCJVOgluwd5OwUoDtnoOxAei8cLXTN7cvEl/skCNDCMPfsUPO5zQwOHIDEvYtMURHe6wOVLgigvOePRyeDkyR4ln7wZ//7XfFBu8B23+aDJjrHGAwza7hjtHJvDmHg7b7Bru7AMjK7Rw2ObBVHDY5oGk9AKQNB2zy8MBTgAAAABJRU5ErkJggg==);
|
||||
background-repeat: no-repeat;
|
||||
position: absolute;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
}
|
||||
.ngGroupingNumber {
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
top: -2px;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.commafeed.frontend.references.nginfinitescroll;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.resource.JavaScriptResourceReference;
|
||||
|
||||
import com.commafeed.frontend.references.angular.AngularReference;
|
||||
|
||||
public class NGInfiniteScrollReference extends JavaScriptResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final NGInfiniteScrollReference INSTANCE = new NGInfiniteScrollReference();
|
||||
|
||||
private NGInfiniteScrollReference() {
|
||||
super(NGInfiniteScrollReference.class, "ng-infinite-scroll.js");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends HeaderItem> getDependencies() {
|
||||
return Arrays.asList(JavaScriptHeaderItem
|
||||
.forReference(AngularReference.INSTANCE));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/* ng-infinite-scroll - v1.0.0 - 2013-02-23 */
|
||||
var mod;
|
||||
|
||||
mod = angular.module('infinite-scroll', []);
|
||||
|
||||
mod.directive('infiniteScroll', [
|
||||
'$rootScope', '$window', '$timeout', function($rootScope, $window, $timeout) {
|
||||
return {
|
||||
link: function(scope, elem, attrs) {
|
||||
var checkWhenEnabled, handler, scrollDistance, scrollEnabled;
|
||||
$window = angular.element($window);
|
||||
scrollDistance = 0;
|
||||
if (attrs.infiniteScrollDistance != null) {
|
||||
scope.$watch(attrs.infiniteScrollDistance, function(value) {
|
||||
return scrollDistance = parseInt(value, 10);
|
||||
});
|
||||
}
|
||||
scrollEnabled = true;
|
||||
checkWhenEnabled = false;
|
||||
if (attrs.infiniteScrollDisabled != null) {
|
||||
scope.$watch(attrs.infiniteScrollDisabled, function(value) {
|
||||
scrollEnabled = !value;
|
||||
if (scrollEnabled && checkWhenEnabled) {
|
||||
checkWhenEnabled = false;
|
||||
return handler();
|
||||
}
|
||||
});
|
||||
}
|
||||
handler = function() {
|
||||
var elementBottom, remaining, shouldScroll, windowBottom;
|
||||
windowBottom = $window.height() + $window.scrollTop();
|
||||
elementBottom = elem.offset().top + elem.height();
|
||||
remaining = elementBottom - windowBottom;
|
||||
shouldScroll = remaining <= $window.height() * scrollDistance;
|
||||
if (shouldScroll && scrollEnabled) {
|
||||
if ($rootScope.$$phase) {
|
||||
return scope.$eval(attrs.infiniteScroll);
|
||||
} else {
|
||||
return scope.$apply(attrs.infiniteScroll);
|
||||
}
|
||||
} else if (shouldScroll) {
|
||||
return checkWhenEnabled = true;
|
||||
}
|
||||
};
|
||||
$window.on('scroll', handler);
|
||||
scope.$on('$destroy', function() {
|
||||
return $window.off('scroll', handler);
|
||||
});
|
||||
return $timeout((function() {
|
||||
if (attrs.infiniteScrollImmediateCheck) {
|
||||
if (scope.$eval(attrs.infiniteScrollImmediateCheck)) {
|
||||
return handler();
|
||||
}
|
||||
} else {
|
||||
return handler();
|
||||
}
|
||||
}), 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
@@ -1,2 +0,0 @@
|
||||
/* ng-infinite-scroll - v1.0.0 - 2013-02-23 */
|
||||
var mod;mod=angular.module("infinite-scroll",[]),mod.directive("infiniteScroll",["$rootScope","$window","$timeout",function(i,n,e){return{link:function(t,l,o){var r,c,f,a;return n=angular.element(n),f=0,null!=o.infiniteScrollDistance&&t.$watch(o.infiniteScrollDistance,function(i){return f=parseInt(i,10)}),a=!0,r=!1,null!=o.infiniteScrollDisabled&&t.$watch(o.infiniteScrollDisabled,function(i){return a=!i,a&&r?(r=!1,c()):void 0}),c=function(){var e,c,u,d;return d=n.height()+n.scrollTop(),e=l.offset().top+l.height(),c=e-d,u=n.height()*f>=c,u&&a?i.$$phase?t.$eval(o.infiniteScroll):t.$apply(o.infiniteScroll):u?r=!0:void 0},n.on("scroll",c),t.$on("$destroy",function(){return n.off("scroll",c)}),e(function(){return o.infiniteScrollImmediateCheck?t.$eval(o.infiniteScrollImmediateCheck)?c():void 0:c()},0)}}}]);
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.commafeed.frontend.references.ngupload;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.resource.JavaScriptResourceReference;
|
||||
|
||||
import com.commafeed.frontend.references.angular.AngularReference;
|
||||
|
||||
public class NGUploadReference extends JavaScriptResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final NGUploadReference INSTANCE = new NGUploadReference();
|
||||
|
||||
private NGUploadReference() {
|
||||
super(NGUploadReference.class, "ng-upload.js");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends HeaderItem> getDependencies() {
|
||||
return Arrays.asList(JavaScriptHeaderItem
|
||||
.forReference(AngularReference.INSTANCE));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
// Version 0.3.2
|
||||
// AngularJS simple file upload directive
|
||||
// this directive uses an iframe as a target
|
||||
// to enable the uploading of files without
|
||||
// losing focus in the ng-app.
|
||||
//
|
||||
// <div ng-app="app">
|
||||
// <div ng-controller="mainCtrl">
|
||||
// <form action="/uploads" ng-upload>
|
||||
// <input type="file" name="avatar"></input>
|
||||
// <input type="submit" value="Upload"
|
||||
// upload-submit="submited(content, completed)"></input>
|
||||
// </form>
|
||||
// </div>
|
||||
// </div>
|
||||
//
|
||||
// angular.module('app', ['ngUpload'])
|
||||
// .controller('mainCtrl', function($scope) {
|
||||
// $scope.submited = function(content, completed) {
|
||||
// if (completed) {
|
||||
// console.log(content);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
//
|
||||
angular.module('ngUpload', [])
|
||||
.directive('uploadSubmit', ['$parse', function($parse) {
|
||||
return {
|
||||
restrict: 'AC',
|
||||
link: function(scope, element, attrs) {
|
||||
// Options (just 1 for now)
|
||||
// Each option should be prefixed with 'upload-options-' or 'uploadOptions'
|
||||
// {
|
||||
// // specify whether to enable the submit button when uploading forms
|
||||
// enableControls: bool
|
||||
// }
|
||||
var options = {};
|
||||
options.enableControls = attrs.uploadOptionsEnableControls;
|
||||
|
||||
// submit the form - requires jQuery
|
||||
var form = element.parents('form[ng-upload]') || element.parents('form.ng-upload');
|
||||
|
||||
// Retrieve the callback function
|
||||
var fn = $parse(attrs.uploadSubmit);
|
||||
|
||||
if (!angular.isFunction(fn)) {
|
||||
var message = "The expression on the ngUpload directive does not point to a valid function.";
|
||||
throw message + "\n";
|
||||
}
|
||||
|
||||
element.bind('click', function($event) {
|
||||
// prevent default behavior of click
|
||||
$event.preventDefault = true;
|
||||
// create a new iframe
|
||||
var iframe = angular.element("<iframe id='upload_iframe' name='upload_iframe' border='0' width='0' height='0' style='width: 0px; height: 0px; border: none; display: none' />");
|
||||
|
||||
// attach function to load event of the iframe
|
||||
iframe.bind('load', function () {
|
||||
// get content - requires jQuery
|
||||
var content = iframe.contents().find('body').text();
|
||||
// execute the upload response function in the active scope
|
||||
scope.$apply(function () {
|
||||
fn(scope, { content: content, completed: true});
|
||||
});
|
||||
// remove iframe
|
||||
if (content !== "") { // Fixes a bug in Google Chrome that dispose the iframe before content is ready.
|
||||
setTimeout(function () { iframe.remove(); }, 250);
|
||||
}
|
||||
element.attr('disabled', null);
|
||||
element.attr('title', 'Click to start upload.');
|
||||
});
|
||||
|
||||
// add the new iframe to application
|
||||
form.parent().append(iframe);
|
||||
|
||||
scope.$apply(function () {
|
||||
fn(scope, {content: "Please wait...", completed: false });
|
||||
});
|
||||
|
||||
var enabled = true;
|
||||
if (!options.enableControls) {
|
||||
// disable the submit control on click
|
||||
element.attr('disabled', 'disabled');
|
||||
enabled = false;
|
||||
}
|
||||
// why do we need this???
|
||||
element.attr('title', (enabled ? '[ENABLED]: ' : '[DISABLED]: ') + 'Uploading, please wait...');
|
||||
|
||||
form.submit();
|
||||
|
||||
}).attr('title', 'Click to start upload.');
|
||||
}
|
||||
};
|
||||
}])
|
||||
.directive('ngUpload', ['$parse', function ($parse) {
|
||||
return {
|
||||
restrict: 'AC',
|
||||
link: function (scope, element, attrs) {
|
||||
element.attr("target", "upload_iframe");
|
||||
element.attr("method", "post");
|
||||
// Append a timestamp field to the url to prevent browser caching results
|
||||
element.attr("action", element.attr("action") + "?_t=" + new Date().getTime());
|
||||
element.attr("enctype", "multipart/form-data");
|
||||
element.attr("encoding", "multipart/form-data");
|
||||
}
|
||||
};
|
||||
}]);
|
||||
@@ -1 +0,0 @@
|
||||
angular.module("ngUpload",[]).directive("uploadSubmit",["$parse",function(t){return{restrict:"AC",link:function(a,e,n){var o={};o.enableControls=n.uploadOptionsEnableControls;var i=e.parents("form[ng-upload]")||e.parents("form.ng-upload"),r=t(n.uploadSubmit);if(!angular.isFunction(r)){var l="The expression on the ngUpload directive does not point to a valid function.";throw l+"\n"}e.bind("click",function(t){t.preventDefault=!0;var n=angular.element("<iframe id='upload_iframe' name='upload_iframe' border='0' width='0' height='0' style='width: 0px; height: 0px; border: none; display: none' />");n.bind("load",function(){var t=n.contents().find("body").text();a.$apply(function(){r(a,{content:t,completed:!0})}),""!==t&&setTimeout(function(){n.remove()},250),e.attr("disabled",null),e.attr("title","Click to start upload.")}),i.parent().append(n),a.$apply(function(){r(a,{content:"Please wait...",completed:!1})});var l=!0;o.enableControls||(e.attr("disabled","disabled"),l=!1),e.attr("title",(l?"[ENABLED]: ":"[DISABLED]: ")+"Uploading, please wait..."),i.submit()}).attr("title","Click to start upload.")}}}]).directive("ngUpload",["$parse",function(){return{restrict:"AC",link:function(t,a){a.attr("target","upload_iframe"),a.attr("method","post"),a.attr("action",a.attr("action")+"?_t="+(new Date).getTime()),a.attr("enctype","multipart/form-data"),a.attr("encoding","multipart/form-data")}}}]);
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.commafeed.frontend.references.spinjs;
|
||||
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.request.Url;
|
||||
import org.apache.wicket.request.resource.UrlResourceReference;
|
||||
|
||||
public class SpinJSReference extends UrlResourceReference {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final SpinJSReference INSTANCE = new SpinJSReference();
|
||||
|
||||
private SpinJSReference() {
|
||||
super(
|
||||
Url.parse("https://cdnjs.cloudflare.com/ajax/libs/spin.js/1.2.7/spin.min.js"));
|
||||
}
|
||||
|
||||
public static void renderHead(final IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.commafeed.frontend.references;
|
||||
package com.commafeed.frontend.resources;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.commafeed.frontend.resources;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import ro.isdc.wro.config.jmx.WroConfiguration;
|
||||
import ro.isdc.wro.http.WroServletContextListener;
|
||||
|
||||
public class WroListener extends WroServletContextListener {
|
||||
|
||||
@Override
|
||||
protected WroConfiguration newConfiguration() {
|
||||
WroConfiguration conf = super.newConfiguration();
|
||||
|
||||
boolean prod = Boolean.valueOf(ResourceBundle.getBundle("application")
|
||||
.getString("production"));
|
||||
|
||||
conf.setDisableCache(prod);
|
||||
conf.setDebug(!prod);
|
||||
return conf;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,69 +5,25 @@ import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.wicket.ajax.WicketEventJQueryResourceReference;
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
|
||||
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
|
||||
import org.apache.wicket.request.cycle.RequestCycle;
|
||||
import org.apache.wicket.request.http.WebResponse;
|
||||
import org.apache.wicket.request.resource.CssResourceReference;
|
||||
import org.apache.wicket.request.resource.JavaScriptResourceReference;
|
||||
import org.apache.wicket.util.io.IOUtils;
|
||||
import org.apache.wicket.util.template.PackageTextTemplate;
|
||||
|
||||
public class WicketUtils {
|
||||
|
||||
public static void loadJQuery(IHeaderResponse response) {
|
||||
response.render(JavaScriptHeaderItem
|
||||
.forReference(WicketEventJQueryResourceReference.get()));
|
||||
}
|
||||
|
||||
public static JavaScriptHeaderItem buildJavaScriptHeaderItem(Class<?> klass) {
|
||||
return JavaScriptHeaderItem
|
||||
.forReference(new JavaScriptResourceReference(klass, klass
|
||||
.getSimpleName() + ".js"));
|
||||
}
|
||||
|
||||
public static void loadJS(IHeaderResponse response, Class<?> klass) {
|
||||
response.render(buildJavaScriptHeaderItem(klass));
|
||||
}
|
||||
|
||||
public static void loadJS(IHeaderResponse response, Class<?> klass,
|
||||
Map<String, ? extends Object> variables) {
|
||||
OnDomReadyHeaderItem result = null;
|
||||
String fileName, Map<String, ? extends Object> variables) {
|
||||
HeaderItem result = null;
|
||||
PackageTextTemplate template = null;
|
||||
try {
|
||||
template = new PackageTextTemplate(klass, klass.getSimpleName()
|
||||
+ ".js");
|
||||
template = new PackageTextTemplate(klass, fileName + ".js");
|
||||
String script = template.asString(variables);
|
||||
result = OnDomReadyHeaderItem.forScript(script);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(template);
|
||||
}
|
||||
response.render(result);
|
||||
}
|
||||
|
||||
public static CssHeaderItem buildCssHeaderItem(Class<?> klass) {
|
||||
return CssHeaderItem.forReference(new CssResourceReference(klass, klass
|
||||
.getSimpleName() + ".css"));
|
||||
}
|
||||
|
||||
public static void loadCSS(IHeaderResponse response, Class<?> klass) {
|
||||
response.render(buildCssHeaderItem(klass));
|
||||
}
|
||||
|
||||
public static void loadCSS(IHeaderResponse response, Class<?> klass,
|
||||
Map<String, ? extends Object> variables) {
|
||||
CssHeaderItem result = null;
|
||||
PackageTextTemplate template = null;
|
||||
try {
|
||||
template = new PackageTextTemplate(klass, klass.getSimpleName()
|
||||
+ ".js");
|
||||
String css = template.asString(variables);
|
||||
result = CssHeaderItem.forCSS(css, null);
|
||||
result = JavaScriptHeaderItem.forScript(script, null);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(template);
|
||||
}
|
||||
|
||||
@@ -3,12 +3,10 @@ package com.commafeed.frontend.utils.exception;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
|
||||
import com.commafeed.frontend.pages.BasePage;
|
||||
import com.commafeed.frontend.references.bootstrap.BootstrapReference;
|
||||
|
||||
public class DisplayExceptionPage extends BasePage {
|
||||
|
||||
@@ -38,10 +36,4 @@ public class DisplayExceptionPage extends BasePage {
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHead(IHeaderResponse response) {
|
||||
BootstrapReference.renderHead(response);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user