Compare commits

..
Author SHA1 Message Date
Luc Charland 8fb5c1d09f Added sort saving to Contacts 2015-08-12 14:39:26 -04:00
Ludovic Marcotte 54334b294e (fix) small fix in the template 2015-08-12 10:31:06 -04:00
Ludovic Marcotte c51bed2580 (fix) updated js/css/map files for packaging 2015-08-12 09:43:55 -04:00
Ludovic Marcotte 935df2bd00 (fix) wrong label name 2015-08-11 21:16:16 -04:00
Ludovic Marcotte 85a843bc1e (fix) now show the event/task list instead of the day/week/month views on sm devices 2015-08-11 20:58:39 -04:00
Ludovic Marcotte 723372dddb (fix) when batch deleting, update the unseen count accordingly 2015-08-11 15:05:31 -04:00
Ludovic Marcotte 9362513fee (fix) moved the mailbox cleanup after expunge in the service 2015-08-11 14:48:45 -04:00
Ludovic Marcotte 2e3057c2ce (fix) calendar views now honor "breakpoints"
We also now use again the default top nav toolbar and we
hide the fab button on sm devices. This of course needs a bit
more work but we are getting there!
2015-08-11 13:40:38 -04:00
Ludovic Marcotte 456649a38a (fix) allow fullsreen editor on sm devices 2015-08-11 13:38:28 -04:00
Ludovic Marcotte 86818d4f64 (fix) fixed scrolling during contact edition 2015-08-11 13:10:11 -04:00
Ludovic Marcotte b59287d6df (fix) removed unused code 2015-08-11 11:18:41 -04:00
Ludovic Marcotte bdc8dfb2b4 (fix) removed unused code 2015-08-11 09:38:53 -04:00
Ludovic Marcotte 2825285b72 (fix) author cleanup 2015-08-11 08:45:05 -04:00
Ludovic Marcotte 314dcfd30e (fix) properly cleanup the Trash folder after empty'ing 2015-08-10 23:48:59 -04:00
Ludovic Marcotte d28fccf71e (fix) open attachment in new window 2015-08-10 23:14:40 -04:00
Ludovic Marcotte ff632ec3e8 (fix) leave some room for the message date 2015-08-10 22:02:43 -04:00
Ludovic Marcotte b7af83f7e3 (feat) pimped the login window 2015-08-10 20:47:58 -04:00
Ludovic Marcotte d2aeee39ef (feat) now able to rename folders w/o double-tap 2015-08-10 14:13:25 -04:00
Ludovic Marcotte ecc0c453d7 (fix) pimped the priority editor 2015-08-10 13:27:35 -04:00
Ludovic Marcotte 420dece1e7 (feat) flag selected messages and mark selected messages as unread 2015-08-10 13:10:45 -04:00
Ludovic Marcotte c738a2dc70 (fix) wrong use of this which was breaking ACL module 2015-08-10 11:02:23 -04:00
Ludovic Marcotte e41e17c5d9 (fix) use proper var:string value 2015-08-10 09:54:14 -04:00
Ludovic Marcotte 5741d7f95c (feat) can now copy selected cards 2015-08-10 09:48:47 -04:00
Ludovic Marcotte e13f7a267b (feat) show email priority 2015-08-09 20:21:09 -04:00
Ludovic Marcotte dd7b929f17 (feat) compose mail with clicked email address 2015-08-09 10:36:54 -04:00
Ludovic Marcotte ad9b969d6d (fix) avoid displaying the chips line 2015-08-07 21:14:17 -04:00
Ludovic Marcotte 704307e6d6 (feat) pimped the mail part viewers 2015-08-07 20:38:26 -04:00
Francis Lachapelle ce8a4b6d8a (js) Make events clickable in month view 2015-08-07 15:32:00 -04:00
Francis Lachapelle 8ab591a1b6 (html) Improve task viewer 2015-08-07 14:25:57 -04:00
Francis Lachapelle 4434547a18 (css) Don't highlight disabled list items 2015-08-07 14:25:14 -04:00
Francis Lachapelle 29d86ad478 (js) Respect user's settings in Calendar module 2015-08-07 14:15:26 -04:00
Ludovic Marcotte 15a5ab0b12 (fix) added tooltip for consistency 2015-08-07 13:46:01 -04:00
Francis Lachapelle 3b5013555d (html) Improve/fix appointment/task viewer/editor 2015-08-07 11:22:24 -04:00
Francis Lachapelle 655a499cd4 (css) Fix subheader margin 2015-08-07 11:18:40 -04:00
Francis Lachapelle 52559087b3 (css) Merge autoScrollList.scss with list.scss 2015-08-07 11:17:09 -04:00
Francis Lachapelle fb7d5b628f (js) Make use of 'controllerAs' in MainUI module 2015-08-07 11:04:04 -04:00
Francis Lachapelle 6e82a7ba7b (js) Indentation 2015-08-07 11:02:34 -04:00
Ludovic Marcotte fbcaf25428 Bumped to v3.0.0 2015-08-07 10:46:45 -04:00
Ludovic Marcotte a17e59af58 (feat) added v3 js/css/map files for packaging 2015-08-07 10:37:36 -04:00
Francis Lachapelle b966fd3e30 (js) Move *.app.js files to their directories 2015-08-07 09:56:47 -04:00
Ludovic Marcotte caa50d25cb (fix) removed broken parts from the template 2015-08-07 09:49:51 -04:00
Francis Lachapelle 636e5c375e (js) Merge utils.js to Common.js 2015-08-07 09:38:21 -04:00
Ludovic Marcotte f6ea2229f8 (fix) reworked the targets to not always generate static files 2015-08-07 09:15:38 -04:00
Francis Lachapelle 7f2ef967b4 Merge pull request #97 from inverse-inc/feature/saveFilterEventsTasks
Reworked saving Events filter and added Tasks filter
2015-08-06 17:49:03 -04:00
Francis Lachapelle 063e973ef3 (css) Cleanup variables already in material 2015-08-06 17:39:01 -04:00
Francis Lachapelle eb543ce14f (js) Allow to change the labels of Dialog.confirm 2015-08-06 17:39:00 -04:00
Francis Lachapelle 9465fbad4b (obj-c) Indentation 2015-08-06 17:39:00 -04:00
Ludovic Marcotte 560feb45d9 (fix) massively pimped the email composer 2015-08-06 16:18:53 -04:00
Ludovic Marcotte b5ca697b43 (fix) imprived the gravatar directive to extract email address between < > 2015-08-06 16:18:10 -04:00
Ludovic Marcotte 33d0f30d97 (fix) avoid closing the email composition window by error 2015-08-06 16:17:31 -04:00
Francis Lachapelle 0d537ab27b Return recurrence rules of occurrence 2015-08-06 16:15:12 -04:00
Francis Lachapelle 2239286697 (js) Use CK Editor in mail account editor (Prefs) 2015-08-06 16:13:10 -04:00
Francis Lachapelle d0d79728d2 (js) Set locale to CKEditor in Mail editor 2015-08-06 16:09:49 -04:00
Francis Lachapelle e6c9289784 Add LocaleCode to JSON defaults 2015-08-06 16:07:46 -04:00
Francis Lachapelle ae017b50bc (js) Improve ckEditor directive
The directive will now consider the following attributes:

- ck-options: a JSON object of options
- ck-locale: the locale code to be used as the language and the speller
  language
2015-08-06 16:04:39 -04:00
Luc Charland 42eb9e51b4 Reworked saving Events filter and added Tasks filter 2015-08-06 14:28:54 -04:00
Francis Lachapelle 8690cee221 Merge pull request #96 from inverse-inc/feature/saveSortEventsTasks
Feature/save sort events tasks
2015-08-06 14:26:33 -04:00
113 changed files with 77267 additions and 724 deletions

No files matched your search

@@ -1493,8 +1493,9 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
// the database. We do this ONLY when using SOGo from the
// Web interface or over ActiveSync.
// Over DAV, it'll be handled directly in PUTAction:
if (![context request] || [[context request] handledByDefaultHandler]
|| [[[context request] requestHandlerKey] isEqualToString: @"Microsoft-Server-ActiveSync"])
if (![context request] ||
[[context request] handledByDefaultHandler] ||
[[[context request] requestHandlerKey] isEqualToString: @"Microsoft-Server-ActiveSync"])
{
// If an alarm was specified, let's use it. This would happen if an attendee accepts/declines/etc. an
// event invitation and also sets an alarm along the way. This would happen ONLY from the web interface.
@@ -84,17 +84,30 @@
*/
- (NSDictionary *) attributesInContext: (WOContext *) context
{
NSArray *rules;
NSArray *allEvents, *rules;
NSCalendarDate *untilDate;
NSMutableDictionary *data, *repeat;
NSString *frequency;
NSTimeZone *timeZone;
SOGoUserDefaults *ud;
iCalEvent *masterComponent;
iCalRecurrenceRule *rule;
data = [NSMutableDictionary dictionaryWithDictionary: [super attributesInContext: context]];
rules = [self recurrenceRules];
if ([self recurrenceId])
{
// If the component is an occurrence of a recurrent component,
// consider the recurrence rules of the master component.
allEvents = [[self parent] events];
masterComponent = [allEvents objectAtIndex: 0];
rules = [masterComponent recurrenceRules];
}
else
{
rules = [self recurrenceRules];
}
if ([rules count] > 0)
{
rule = [rules objectAtIndex: 0];
+10 -8
View File
@@ -408,16 +408,17 @@
- (id <WOActionResults>) copyAction
{
WORequest *request;
id <WOActionResults> response;
NSString *destinationFolderId;
NSArray *contactsId;
NSDictionary *data;
NSException *ex;
request = [context request];
data = [[[context request] contentAsString] objectFromJSONString];
contactsId = [data objectForKey: @"uids"];
destinationFolderId = [data objectForKey: @"folder"];
if ((destinationFolderId = [request formValueForKey: @"folder"]) &&
(contactsId = [request formValuesForKey: @"uid"]))
if (destinationFolderId && [contactsId count])
ex = [self _moveContacts: contactsId
toFolder: destinationFolderId
andKeepCopy: YES];
@@ -436,16 +437,17 @@
- (id <WOActionResults>) moveAction
{
WORequest *request;
id <WOActionResults> response;
NSString *destinationFolderId;
NSDictionary *data;
NSArray *contactsId;
NSException *ex;
request = [context request];
data = [[[context request] contentAsString] objectFromJSONString];
contactsId = [data objectForKey: @"uids"];
destinationFolderId = [data objectForKey: @"folder"];
if ((destinationFolderId = [request formValueForKey: @"folder"])
&& (contactsId = [request formValuesForKey: @"uid"]))
if (destinationFolderId && [contactsId count])
ex = [self _moveContacts: contactsId
toFolder: destinationFolderId
andKeepCopy: NO];
+26
View File
@@ -39,6 +39,8 @@
#import <Contacts/SOGoContactFolder.h>
#import <Contacts/SOGoContactFolders.h>
#import <SOGo/SOGoUserSettings.h>
#import <NGCards/NGVCard.h>
#import <NGCards/NGVList.h>
#import <SoObjects/Contacts/SOGoContactGCSEntry.h>
@@ -81,10 +83,34 @@
s = [rq formValueForKey: @"sort"];
if (![s length])
s = [self defaultSortKey];
else
[self saveSortValue: s];
return s;
}
- (void) saveSortValue: (NSString *) sort
{
NSString *ascending;
SOGoUserSettings *us;
NSMutableDictionary *contactSettings;
ascending = [[context request] formValueForKey: @"asc"];
if ([sort length])
{
us = [[context activeUser] userSettings];
contactSettings = [us objectForKey: @"Contact"];
// Must create if it doesn't exist
if (!contactSettings)
{
contactSettings = [NSMutableDictionary dictionary];
[us setObject: contactSettings forKey: @"Contact"];
}
[contactSettings setObject: [NSArray arrayWithObjects: [sort lowercaseString], [NSString stringWithFormat: @"%d", (ascending?1:0)], nil] forKey: @"SortingState"];
[us synchronize];
}
}
- (NSArray *) contactInfos
{
id <SOGoContactFolder> folder;
@@ -9,6 +9,7 @@
"Connect" = "Connect";
"Authentication Failed" = "Authentication Failed";
"Wrong username or password." = "Wrong username or password.";
"cookiesNotEnabled" = "You cannot login because your browser's cookies are disabled. Please enable cookies in your browser's settings and try again.";
+25 -20
View File
@@ -61,7 +61,8 @@ static SoProduct *preferencesProduct = nil;
SOGoUserDefaults *defaults;
NSMutableArray *accounts;
NSArray *categoryLabels;
NSDictionary *locale;
if (!preferencesProduct)
{
preferencesProduct = [[SoProduct alloc] initWithBundle:
@@ -78,7 +79,7 @@ static SoProduct *preferencesProduct = nil;
if (![[defaults source] objectForKey: @"SOGoTimeZone"])
[[defaults source] setObject: [defaults timeZoneName] forKey: @"SOGoTimeZone"];
if (![[defaults source] objectForKey: @"SOGoShortDateFormat"])
[[defaults source] setObject: [defaults shortDateFormat] forKey: @"SOGoShortDateFormat"];
@@ -90,7 +91,7 @@ static SoProduct *preferencesProduct = nil;
if (![[defaults source] objectForKey: @"SOGoLoginModule"])
[[defaults source] setObject: [defaults loginModule] forKey: @"SOGoLoginModule"];
if (![[defaults source] objectForKey: @"SOGoRefreshViewCheck"])
[[defaults source] setObject: [defaults refreshViewCheck] forKey: @"SOGoRefreshViewCheck"];
@@ -99,13 +100,13 @@ static SoProduct *preferencesProduct = nil;
//
if (![[defaults source] objectForKey: @"SOGoFirstDayOfWeek"])
[[defaults source] setObject: [NSNumber numberWithInt: [defaults firstDayOfWeek]] forKey: @"SOGoFirstDayOfWeek"];
if (![[defaults source] objectForKey: @"SOGoDayStartTime"])
[[defaults source] setObject: [NSString stringWithFormat: @"%02d:00", [defaults dayStartHour]] forKey: @"SOGoDayStartTime"];
if (![[defaults source] objectForKey: @"SOGoDayEndTime"])
[[defaults source] setObject: [NSString stringWithFormat: @"%02d:00", [defaults dayEndHour]] forKey: @"SOGoDayEndTime"];
if (![[defaults source] objectForKey: @"SOGoFirstWeekOfYear"])
[[defaults source] setObject: [defaults firstWeekOfYear] forKey: @"SOGoFirstWeekOfYear"];
@@ -114,20 +115,20 @@ static SoProduct *preferencesProduct = nil;
if (![[defaults source] objectForKey: @"SOGoCalendarEventsDefaultClassification"])
[[defaults source] setObject: [defaults calendarEventsDefaultClassification] forKey: @"SOGoCalendarEventsDefaultClassification"];
if (![[defaults source] objectForKey: @"SOGoCalendarTasksDefaultClassification"])
[[defaults source] setObject: [defaults calendarTasksDefaultClassification] forKey: @"SOGoCalendarTasksDefaultClassification"];
if (![[defaults source] objectForKey: @"SOGoCalendarDefaultReminder"])
[[defaults source] setObject: [defaults calendarDefaultReminder] forKey: @"SOGoCalendarDefaultReminder"];
// Populate default calendar categories, based on the user's preferred language
if (![defaults calendarCategories])
{
categoryLabels = [[[self labelForKey: @"calendar_category_labels" withResourceManager: [preferencesProduct resourceManager]]
componentsSeparatedByString: @","]
sortedArrayUsingSelector: @selector (localizedCaseInsensitiveCompare:)];
[defaults setCalendarCategories: categoryLabels];
}
if (![defaults calendarCategoriesColors])
@@ -143,7 +144,7 @@ static SoProduct *preferencesProduct = nil;
[defaults setCalendarCategoriesColors: colors];
}
//
// Default Contacts preferences
//
@@ -154,10 +155,10 @@ static SoProduct *preferencesProduct = nil;
categoryLabels = [[[self labelForKey: @"contacts_category_labels" withResourceManager: [preferencesProduct resourceManager]]
componentsSeparatedByString: @","]
sortedArrayUsingSelector: @selector (localizedCaseInsensitiveCompare:)];
if (!categoryLabels)
categoryLabels = [NSArray array];
[defaults setContactsCategories: categoryLabels];
}
@@ -172,27 +173,27 @@ static SoProduct *preferencesProduct = nil;
if (![[defaults source] objectForKey: @"SOGoMailReplyPlacement"])
[[defaults source] setObject: [defaults mailReplyPlacement] forKey: @"SOGoMailReplyPlacement"];
if (![[defaults source] objectForKey: @"SOGoMailSignaturePlacement"])
[[defaults source] setObject: [defaults mailSignaturePlacement] forKey: @"SOGoMailSignaturePlacement"];
if (![[defaults source] objectForKey: @"SOGoMailComposeMessageType"])
[[defaults source] setObject: [defaults mailComposeMessageType] forKey: @"SOGoMailComposeMessageType"];
if (![[defaults source] objectForKey: @"SOGoMailDisplayRemoteInlineImages"])
[[defaults source] setObject: [defaults mailDisplayRemoteInlineImages] forKey: @"SOGoMailDisplayRemoteInlineImages"];
// Populate default mail lablels, based on the user's preferred language
if (![[defaults source] objectForKey: @"SOGoMailLabelsColors"])
{
SOGoMailLabel *label;
NSArray *labels;
id v;
int i;
v = [defaults mailLabelsColors];
labels = [SOGoMailLabel labelsFromDefaults: v component: self];
v = [NSMutableDictionary dictionary];
for (i = 0; i < [labels count]; i++)
@@ -201,7 +202,7 @@ static SoProduct *preferencesProduct = nil;
[v setObject: [NSArray arrayWithObjects: [label label], [label color], nil]
forKey: [label name]];
}
[defaults setMailLabelsColors: v];
}
@@ -214,6 +215,10 @@ static SoProduct *preferencesProduct = nil;
//
values = [[[[defaults source] values] mutableCopy] autorelease];
// Add locale code (used by CK Editor)
locale = [[preferencesProduct resourceManager] localeForLanguageNamed: [defaults language]];
[values setObject: [locale objectForKey: @"NSLocaleCode"] forKey: @"LocaleCode"];
accounts = [NSMutableArray arrayWithArray: [values objectForKey: @"AuxiliaryMailAccounts"]];
account = [[[context activeUser] mailAccounts] objectAtIndex: 0];
if (![account objectForKey: @"receipts"])
+13 -3
View File
@@ -652,10 +652,11 @@ static NSArray *tasksFields = nil;
return [self _responseWithData: data];
}
- (void) saveEventFilterValue
- (void) saveFilterValue: (NSString *) submodule
{
NSString *filter;
SOGoUserSettings *us;
NSMutableDictionary *calendarSettings;
filter = [[context request] formValueForKey: @"filterpopup"];
if ([filter length]
@@ -663,7 +664,15 @@ static NSArray *tasksFields = nil;
&& ![filter isEqualToString: @"view_future"])
{
us = [[context activeUser] userSettings];
[us setObject: filter forKey: @"CalendarDefaultFilter"];
calendarSettings = [us objectForKey: @"Calendar"];
// Must create if it doesn't exist
if (!calendarSettings)
{
calendarSettings = [NSMutableDictionary dictionary];
[us setObject: calendarSettings forKey: @"Calendar"];
}
//[us setObject: filter forKey: submodule];
[calendarSettings setObject: filter forKey: submodule];
[us synchronize];
}
}
@@ -743,7 +752,7 @@ static NSArray *tasksFields = nil;
NSString *sort, *ascending;
[self _setupContext];
[self saveEventFilterValue];
[self saveFilterValue: @"EventsFilterState"];
[self saveSortValue: @"EventsSortingState"];
newEvents = [NSMutableArray array];
@@ -1436,6 +1445,7 @@ _computeBlocksPosition (NSArray *blocks)
filteredTasks = [NSMutableArray array];
[self _setupContext];
[self saveFilterValue: @"TasksFilterState"];
[self saveSortValue: @"TasksSortingState"];
startSecs = (unsigned int) [startDate timeIntervalSince1970];
+4 -1
View File
@@ -33,6 +33,7 @@
#import <NGCards/iCalPerson.h>
#import <SOGo/NSArray+Utilities.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoPermissions.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoUserDefaults.h>
@@ -261,12 +262,14 @@
- (WOResponse *) saveSelectedListAction
{
WORequest *request;
NSDictionary *params;
NSString *selectedList;
[self _setupContext];
request = [context request];
params = [[request contentAsString] objectFromJSONString];
selectedList = [request formValueForKey: @"list"];
selectedList = [params objectForKey: @"list"];
[moduleSettings setObject: selectedList
forKey: @"SelectedList"];
[us synchronize];
@@ -5,8 +5,8 @@
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label">
<md-content md-scroll-y="true" class="md-padding md-whiteframe-z1 bg-sogoPaper-50">
<div class="editor md-padding">
<md-content md-scroll-y="md-scroll-y" class="viewer md-padding md-whiteframe-z1 bg-sogoPaper-50">
<!-- <div class="editor md-padding">-->
<hgroup class="header">
<h1 class="sg-md-display-2--light" ng-bind-html="editor.card.$fullname()"><!-- fullname --></h1>
<h6 class="sg-md-display-2-subheader">{{editor.card.$description()}}</h6>
@@ -342,7 +342,7 @@
</var:if>
</div>
</form>
</div>
<!-- </div> -->
</md-content>
</container>
@@ -72,31 +72,6 @@
<!-- TEMPLATE SCRIPT WRAPPER -->
<script type="text/ng-template" id="UIxContactFoldersView">
<!-- dropdown menu for addressbook options button -->
<div id="addressbookProperties" class="f-dropdown icons-dropdown" ng-hide="true">
<ul class="button-group">
<li label:tooltip="Links to this Address Book"
tooltip-popup-delay="500">
<span class="button"
sg-dropdown-content-toggle="#addressbookLinks">
<i class="icon-hyperlink"><!-- links --></i>
</span>
</li>
<li label:tooltip="Rename"
tooltip-popup-delay="500">
<span class="button" ng-click="edit()">
<i class="icon-pencil"><!-- rename --></i>
</span>
</li>
<li label:tooltip="Import Cards"
tooltip-popup-delay="500">
<span class="button" ng-click="importCards()">
<i class="icon-file"><!-- import --></i>
</span>
</li>
</ul>
</div>
<!-- Sidenav -->
<md-sidenav id="left-sidenav" class="md-sidenav-left md-whiteframe-z1" md-component-id="left" md-is-locked-open="isGtMedium" layout="column">
<var:component className="UIxSidenavToolbarTemplate" />
@@ -106,7 +81,7 @@
<section>
<md-subheader class="sg-md-subheader">
<div layout="row" layout-align="space-between center">
<span><var:string label:value="AddressBooks"/></span>
<span><var:string label:value="Address Books"/></span>
<md-button class="sg-icon-button"
label:aria-label="New Addressbook..."
ng-click="app.newAddressbook()">
@@ -140,6 +115,11 @@
ng-click="$mdOpenMenu()"
md-menu-origin="md-menu-origin">more_vert</md-icon>
<md-menu-content width="2">
<md-menu-item>
<md-button type="button" ng-click="app.edit(folder)">
<var:string label:value="Rename"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button type="button" ng-click="app.confirmDelete()">
<var:string label:value="Delete"/>
@@ -205,6 +185,11 @@
ng-click="$mdOpenMenu()"
md-menu-origin="md-menu-origin">more_vert</md-icon>
<md-menu-content width="2">
<md-menu-item>
<md-button type="button" ng-click="app.edit(folder)">
<var:string label:value="Rename"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button type="button" ng-click="app.confirmDelete(folder)">
<var:string label:value="Delete"/>
@@ -343,6 +328,24 @@
<md-button class="sg-icon-button" ng-click="addressbook.confirmDeleteSelectedCards()">
<md-icon>delete</md-icon>
</md-button>
<md-menu>
<md-button class="sg-icon-button" label:aria-label="Copy contacts" ng-click="$mdOpenMenu()">
<md-tooltip md-direction="left"><var:string label:value="Copy To"/></md-tooltip>
<md-icon>content_copy</md-icon>
</md-button>
<md-menu-content width="4">
<md-menu-item>
<md-button class="md-primary" ng-disabled="true"><var:string label:value="Address Books"/></md-button>
</md-menu-item>
<md-menu-divider><!-- divider --></md-menu-divider>
<md-menu-item ng-repeat="folder in app.service.$addressbooks track by folder.id"
ng-hide="addressbook.selectedFolder.id == folder.id">
<md-button ng-click="addressbook.copySelectedCards(folder.id)">
<span ng-class="'sg-child-level-' + folder.level">{{folder.name}}</span>
</md-button>
</md-menu-item>
</md-menu-content>
</md-menu>
<md-menu>
<md-button class="sg-icon-button" label:aria-label="More messages options" ng-click="$mdOpenMenu()">
<md-icon>more_vert</md-icon>
@@ -371,22 +374,8 @@
<span ng-show="addressbook.selectedFolder.cards.length == 0"><var:string label:value="No contact"/></span>
</h2>
</header>
<!-- Search field & special results
<input type="text" placeholder="Search" ng-model="search.filter" ng-keyup="doSearch($event)" />
<div ng-switch="search.status">
<div ng-switch-when="min-char" class="alert-bg">
<i class="icon-warning"></i><var:string label:value="Please enter at least three characters"/>
</div>
<div ng-switch-when="no-result" class="alert-bg">
<i class="icon-ion-search"></i><var:string label:value="No matching card"/>
</div>
<div ng-switch-when="remote-addressbook" ng-show="addressbook.cards.length == 0" class="alert-bg">
<i class="icon-ion-search"></i><var:string label:value="Initiate a search"/>
</div>
</div>
-->
<md-virtual-repeat-container class="md-flex">
<md-list>
<md-list class="sg-section-list">
<div md-virtual-repeat="currentCard in addressbook.selectedFolder.cards">
<md-list-item
ng-class="{'sg-active': currentCard.id == addressbook.selectedFolder.selectedCard}"
@@ -250,7 +250,7 @@
<label class="pseudo-input-label"><var:string label:value="Attendees"/></label>
<!-- md-contact-chips don't support "readonly", so we build them using md-chips
in readonly mode and a template similar to the one of md-contact-chips -->
<md-chips class="md-contact-chips"
<md-chips class="md-contact-chips sg-readonly"
ng-model="part.participants"
readonly="true">
<md-chip-template>
@@ -11,13 +11,14 @@
var:title="filenameForDisplay"
class="md-card-image"></img>
<md-card-content>
<p>
<p class="md-caption">
<var:string value="filenameForDisplay" /><br/>
<var:string value="bodyInfo.size" formatter="sizeFormatter"/>
</p>
</md-card-content>
<div class="md-actions" layout="row" layout-align="end center">
<md-button class="sg-icon-button" var:href="pathForDownload">
<md-tooltip md-direction="left"><var:string label:value="Save Attachment"/></md-tooltip>
<md-icon>save</md-icon>
</md-button>
</div>
@@ -4,24 +4,16 @@
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label">
<md-whiteframe class="md-whiteframe-z1" layout="row" layout-align="space-between center">
<div layout="row">
<div>
<md-card>
<md-card-content>
<img var:src="mimeImageURL"/>
</div>
<div layout="column" layout-align="start start" layout-padding="layout-padding">
<div>
<var:string value="filenameForDisplay"/>
</div>
<div class="md-caption">
<p class="md-caption">
<var:string value="filenameForDisplay"/><br/>
<var:string value="bodyInfo.size" formatter="sizeFormatter"/>
</div>
</div>
</div>
<div layout="row" layout-align="end end">
<md-button class="sg-icon-button" var:href="pathToAttachment">
</p>
</md-card-content>
<div class="md-actions" layout="row" layout-align="end center">
<md-button class="sg-icon-button" var:href="pathToAttachment" target="_blank">
<md-tooltip md-direction="left"><var:string label:value="View Attachment"/></md-tooltip>
<md-icon>open_in_browser</md-icon>
</md-button>
@@ -50,5 +42,5 @@
PartPath: <var:string value="partPath" /><br />
-->
</md-whiteframe>
</md-card>
</div>
+121 -101
View File
@@ -7,70 +7,34 @@
<md-dialog flex="80" flex-sm="100">
<md-toolbar class="md-padding">
<!-- TOOLBAR TO SHOW CC/BCC/ATTACHMENT FIELDS -->
<div class="md-toolbar-tools">
<md-icon class="material-icons sg-icon-toolbar-bg">edit</md-icon>
<md-button ng-show="editor.hideCc" ng-click="editor.hideCc = false">Cc</md-button>
<md-button ng-show="editor.hideBcc" ng-click="editor.hideBcc = false">Bcc</md-button>
<md-button>
<label for="file-input">
Add files
</label>
<!-- FROM -->
<sg-avatar-image class="md-tile-left" hide-sm="hide-sm" sg-email="editor.message.editable.from" size="32"><!-- avatar --></sg-avatar-image>
<md-input-container flex="flex">
<label><var:string label:value="From"/></label>
<md-select name="from"
ng-model="editor.message.editable.from">
<md-option ng-value="identity" ng-repeat="identity in editor.identities">{{identity}}</md-option>
</md-select>
</md-input-container>
<div flex-gt-sm="flex-gt-sm"><!-- spacer --></div>
<md-button class="sg-icon-button" ng-click="editor.send()">
<md-icon>send</md-icon>
</md-button>
<input id="file-input" type="file"
nv-file-select="nv-file-select"
multiple="multiple"
uploader="editor.uploader"
ng-show="false"/>
<md-menu>
<md-button label:aria-label="More mail options" class="iconBtton" ng-click="$mdOpenMenu($event)">
<md-icon>more_vert</md-icon>
</md-button>
<md-menu-content width="4">
<md-menu-item>
<md-button>
<md-checkbox ng-model="editor.message.editable.receipt">
<var:string label:value="Receipt"/>
</md-checkbox>
</md-button>
</md-menu-item>
<md-menu-item>
<div layout="row" layout-align="center center">
<span>
<var:string label:value="Priority"/>
</span>
<md-slider flex="flex"
md-discrete="md-discrete"
ng-model="editor.message.editable.priority"
step="1"
min="1"
max="5"
label:aria-label="Priority">
</md-slider>
</div>
</md-menu-item>
</md-menu-content>
</md-menu>
</div>
<md-button class="sg-icon-button " ng-click="editor.message.$save()">
<md-icon>save</md-icon>
</md-button>
<md-button class="sg-icon-button " ng-click="editor.cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<form>
<header>
<!-- FROM / TO / CC/ BCC / SUBJECT / ATTACHMENTS -->
<!-- TO / CC/ BCC / SUBJECT / ATTACHMENTS -->
<div class="msg-header-content">
<md-input-container>
<label> <var:string label:value="From"/></label>
<md-select name="from"
ng-model="editor.message.editable.from">
<md-option ng-value="identity" ng-repeat="identity in editor.identities">{{identity}}</md-option>
</md-select>
</md-input-container>
<div class="pseudo-input-container">
<label class="pseudo-input-label">
@@ -129,57 +93,113 @@
</label>
<input type="text" name="subject" ng-model="editor.message.editable.subject"/>
</md-input-container>
<md-list>
<!-- FILES ALREADY UPLOADED, FOR EXAMPLE WHEN WE FORWARD A
MAIL WITH ATTACHMENTS -->
<md-list-item ng-repeat="item in editor.message.editable.attachmentAttrs">
<div layout="row" layout-align="space-between center">
<span ng-bind="item.filename"><!-- filename --></span>
<md-button class="sg-icon-button"
ng-click="editor.message.$deleteAttachment(item.filename);">
<md-icon>remove_circle_outline</md-icon>
</md-button>
</div>
</md-list-item>
<!-- FILE BEING ATTACHED TO A MAIL -->
<md-list-item ng-repeat="item in editor.uploader.queue">
<div layout="row" layout-align="space-between center">
<span ng-bind="item.file.name"><!-- filename --></span>
<md-progress-linear md-mode="determinate"
value="{{item.progress}}"
ng-show="item.isUploading" ><!-- progress--></md-progress-linear>
<md-button class="sg-icon-button"
ng-click="editor.uploader.cancelItem(item)"
ng-show="item.isUploading">
<md-icon>cancel</md-icon>
</md-button>
<md-button class="sg-icon-button"
ng-click="editor.message.$deleteAttachment(item.file.name); item.remove();"
ng-show="!item.isUploading">
<md-icon>remove_circle_outline</md-icon>
</md-button>
</div>
</md-list-item>
</md-list>
</div>
<!-- TOOLBAR TO SHOW CC/BCC/ATTACHMENT FIELDS -->
<div layout="column" layout-align="start end">
<md-button class="sg-icon-button " ng-show="editor.hideCc" ng-click="editor.hideCc = false">Cc</md-button>
<md-button class="sg-icon-button " ng-show="editor.hideBcc" ng-click="editor.hideBcc = false">Bcc</md-button>
<md-menu>
<md-button label:aria-label="More mail options" class="sg-icon-button" ng-click="$mdOpenMenu($event)">
<md-icon>more_vert</md-icon>
</md-button>
<md-menu-content width="4">
<md-menu-item>
<md-button>
<md-checkbox ng-model="editor.message.editable.receipt">
<var:string label:value="Return Receipt"/>
</md-checkbox>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button class="md-primary" ng-disabled="true"><var:string label:value="Priority"/></md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 1">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 1}"><!-- highest --></md-icon>
<var:string label:value="highest"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 2">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 2}"><!-- high --></md-icon>
<var:string label:value="high"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 3">
<md-icon ng-class="{ 'icon-check':
!editor.message.editable.priority
|| editor.message.editable.priority == 3}"><!-- normal --></md-icon>
<var:string label:value="normal"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 4">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 4}"><!-- low --></md-icon>
<var:string label:value="low"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="editor.message.editable.priority = 5">
<md-icon ng-class="{ 'icon-check': editor.message.editable.priority == 5}"><!-- lowest --></md-icon>
<var:string label:value="lowest"/>
</md-button>
</md-menu-item>
</md-menu-content>
</md-menu>
</div>
</header>
<!-- MESSAGE CONTENT -->
<textarea name="content" var:class="editorClass"
ck-locale="editor.localeCode"
ng-model="editor.message.editable.text"/>
<!-- TOOLBAR BUTTONS -->
<div class="buttonsToolbar">
<div layout="row" layout-align="end center">
<md-button ng-click="editor.cancel()"><var:string label:value="Cancel"/></md-button>
<md-button ng-click="editor.message.$save()"><var:string label:value="Save"/></md-button>
<md-button class="fg-sogoBlue-700 md-primary md-hue-3"
ng-click="editor.send()"><var:string label:value="Send"/></md-button>
</div>
</div>
</form>
</md-dialog-content>
</md-dialog>
<!-- TOOLBAR BUTTONS -->
<div class="md-actions">
<div layout="row" layout-align="space-between center" layout-fill="layout-fill">
<div>
<md-button>
<md-icon>attach_file</md-icon>
<label for="file-input">
Attach
</label>
</md-button>
<input id="file-input" type="file"
nv-file-select="nv-file-select"
multiple="multiple"
uploader="editor.uploader"
ng-show="false"/>
</div>
<div>
<!-- FILES ALREADY UPLOADED, FOR EXAMPLE WHEN WE FORWARD A
MAIL WITH ATTACHMENTS -->
<md-chips ng-model="editor.message.editable.attachmentAttrs"
class="sg-readonly" readonly="true">
<md-chip-template>
<span>{{$chip.filename}}</span>
<md-icon ng-click="editor.message.$deleteAttachment($chip.filename);">close</md-icon>
</md-chip-template>
</md-chips>
<!-- FILE BEING ATTACHED TO A MAIL -->
<md-chips ng-model="editor.uploader.queue"
class="sg-readonly" readonly="true">
<md-chip-template>
<span>{{$chip.file.name}}</span>
<md-icon ng-show="!$chip.isUploading"
ng-click="editor.message.$deleteAttachment($chip.file.name);
$chip.remove();">close</md-icon>
<md-icon ng-show="$chip.isUploading"
ng-click="editor.uploader.cancelItem($chip)"
ng-style="{ 'color': '#F00' }">cancel</md-icon>
<span ng-show="$chip.isUploading">{{$chip.progress}} %</span>
</md-chip-template>
</md-chips>
</div>
</div>
</div>
</md-dialog>
</container>
@@ -13,7 +13,7 @@
</h2>
</header>
<md-virtual-repeat-container class="md-flex">
<md-list>
<md-list class="sg-section-list">
<div md-virtual-repeat="currentMessage in mailbox.selectedFolder.$messages">
<md-list-item
ng-class="{'sg-active': currentMessage.uid == mailbox.selectedFolder.selectedMessage, unread: !currentMessage.isread}"
@@ -37,6 +37,7 @@
ng-hide="mailbox.selectedFolder.$loadMessage(currentMessage.uid)"><!-- loading --></i>
</div>
<div class="sg-tile-icons">
<md-icon ng-show="currentMessage.priority == 'highest' || currentMessage.priority == 'high'">warning</md-icon>
<md-icon ng-show="currentMessage.isflagged">star</md-icon>
<md-icon ng-show="currentMessage.isanswered">reply</md-icon>
<md-icon ng-show="currentMessage.isforwarded">forward</md-icon>
+8 -3
View File
@@ -287,12 +287,17 @@
<var:string label:value="New Subfolder..."/>
</md-button>
</md-menu-item>
<md-menu-item ng-show="folder.$isEditable">
<md-button type="button" ng-click="app.editFolder(folder)">
<var:string label:value="Rename"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button type="button" ng-click="app.compactFolder(folder)">
<var:string label:value="Compact"/>
</md-button>
</md-menu-item>
<md-menu-item ng-show="folder.$isEditable">
<md-menu-item ng-show="folder.$isEditable">
<md-button type="button" ng-click="app.confirmDelete(folder)">
<var:string label:value="Delete"/>
</md-button>
@@ -472,12 +477,12 @@
</md-button>
<md-menu-content width="2">
<md-menu-item>
<md-button>
<md-button ng-click="mailbox.markSelectedMessagesAsFlagged()">
<var:string label:value="Flag"/>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button>
<md-button ng-click="mailbox.markSelectedMessagesAsUnread()">
<var:string label:value="Mark as Unread"/>
</md-button>
</md-menu-item>
+11 -5
View File
@@ -21,7 +21,9 @@
<var:string label:value="From"/>
</label>
<div class="pseudo-input-field">
<a ng-href="mailto:{{viewer.message.from[0].email}}" ng-bind="viewer.message.from[0].full"><!-- from --></a>
<a href="#"
ng-bind="viewer.message.from[0].full"
ng-click="viewer.newMessage($event, viewer.message.from[0])"><!-- from --></a>
</div>
</div>
@@ -30,7 +32,9 @@
<var:string label:value="To"/>
</label>
<div class="pseudo-input-field">
<a ng-href="mailto:{{viewer.message.to[0].email}}" ng-bind="viewer.message.to[0].full"><!-- to --></a>
<a href="#"
ng-bind="viewer.message.to[0].full"
ng-click="viewer.newMessage($event, viewer.message.to[0])"><!-- to --></a>
</div>
</div>
@@ -136,9 +140,11 @@
<div class="msg-date sg-md-body-multi">
<time datetime="viewer.message.date" ng-bind="viewer.message.date"><!-- date --></time>
</div>
<div class="mailer_mailcontent" ng-repeat="part in viewer.message.$content()">
<div ng-if="part.html" ng-bind-html="part.content"><!-- msg --></div>
<div ng-if="part.compile" sg-compile="part.content"><!-- msg --></div>
<div layout="row" layout-wrap="layout-wrap">
<div ng-class="part.msgclass" layout="row" layout-wrap="layout-wrap" class="mailer_mailcontent" ng-repeat="part in viewer.message.$content()">
<div ng-if="part.html" ng-bind-html="part.content"><!-- msg --></div>
<div ng-if="part.compile" sg-compile="part.content"><!-- msg --></div>
</div>
</div>
</div>
</md-content>
+28 -59
View File
@@ -7,7 +7,7 @@
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label"
const:jsFiles="Main.app.js, Common.js"
const:jsFiles="Main.js, Common.js"
>
<!--
MAIN CONTENT ROW
@@ -17,30 +17,11 @@
-->
<main class="view md-layout-fill md-layout-padding" ui-view="login" layout="row" layout-align="center start">
<md-content class="md-padding" md-scroll-y="true">
<div ng-controller="loginController">
<div class="sg-login" ng-controller="LoginController as app">
<script type="text/javascript">
var cookieUsername = '<var:string var:value="cookieUsername" const:escapeHTML="NO"/>';
</script>
<!-- <div id="aboutBox" style="display:none;">
<div>
<p class="logo"><img const:alt="SOGo" rsrc:src="img/sogo-logo.png"/></p>
<p>Version <var:string value="version"/> <span class="buildDate">(<var:string value="buildDate" />)</span></p>
<p class="scroll"><var:string label:value="AboutBox" const:escapeHTML="NO"/></p>
<img const:alt="Inverse" rsrc:src="img/inverse.png"/>
<p class="links"><a href="http://sogo.nu/" target="_new">sogo.nu</a> /
<a href="http://inverse.ca/" target="_new">inverse.ca</a></p>
<p><a id="aboutClose" href="#" class="button">
<span><var:string label:value="OK" /></span></a></p>
</div>
</div> -->
<!-- <nav class="top-bar">
<section class="top-bar-section">
<ul class="right">
<li><a href="#"><var:string label:value="About" /></a></li>
</ul>
</section>
</nav> -->
<div id="login">
<div id="logo">
<img const:alt="*" id="splash" rsrc:src="img/sogo-full.svg"/>
@@ -48,28 +29,22 @@
<form name="loginForm" layout="column"
ng-cloak="ng-cloak"
ng-controller="loginController"
ng-submit="login(creds)">
ng-submit="app.login()">
<var:if condition="hasLoginSuffix">
<input type="hidden" ng-model="creds.loginSuffix" var:value="loginSuffix"/>
<input type="hidden" ng-model="app.creds.loginSuffix" var:value="loginSuffix"/>
</var:if>
<div ng-show="warning" ng-cloak="ng-cloak" alert="alert" class="alert-box radius warning">{{warning}}</div>
<md-input-container>
<label>
<var:string label:value="Username"/>
</label>
<input autocapitalize="off" type="text" ng-model="creds.username" required="required" />
<md-icon>person</md-icon>
<input autocapitalize="off" type="text" ng-model="app.creds.username" ng-required="true" label:placeholder="Username"/>
</md-input-container>
<md-input-container>
<label>
<var:string label:value="Password"/>
</label>
<input type="password" ng-model="creds.password" required="required" />
<md-input-container md-no-float="md-no-float">
<md-icon>email</md-icon>
<input type="password" ng-model="app.creds.password" ng-required="true" label:placeholder="Password"/>
</md-input-container>
<!-- CONNECT BUTTON -->
<div layout="row" layout-align="end center">
<md-button class="md-raised" type="submit" ng-disabled='!loginForm.$valid'>
<md-button class="md-raised" type="submit" ng-disabled='app.loginForm.$invalid'>
<span>
<var:string label:value="Connect"/>
</span>
@@ -78,38 +53,32 @@
<!-- LANGUAGES SELECT -->
<div layout="row" layout-align="start end">
<md-input-container>
<label class="login-lang">
<var:string label:value="Language"/>
</label>
<md-select flex="true" ng-model="creds.language">
<var:foreach list="languages" item="item">
<md-option var:value="item">
<var:string value="languageText"/>
</md-option>
</var:foreach>
<md-icon>language</md-icon>
<md-select flex="true" ng-model="app.creds.language" label:placeholder="choose">
<var:foreach list="languages" item="item">
<md-option var:value="item">
<var:string value="languageText"/>
</md-option>
</var:foreach>
</md-select>
</md-input-container>
</div>
<!-- DOMAINS SELECT -->
<var:if condition="hasLoginDomains">
<div layout="row" layout-align="start end">
<label>
<var:string label:value="Domain"/>
</label>
<md-select flex="true" ng-model="creds.domain" label:placeholder="choose">
<var:foreach list="loginDomains" item="item">
<md-option var:value="item">
<var:string value="item"/>
</md-option>
</var:foreach>
</md-select>
<md-icon>domain</md-icon>
<md-select class="md-flex" ng-model="app.creds.domain" label:placeholder="choose">
<var:foreach list="loginDomains" item="item">
<md-option var:value="item">
<var:string value="item"/>
</md-option>
</var:foreach>
</md-select>
</div>
</var:if>
<div layout="row" layout-align="center center">
<md-switch ng-model="creds.rememberLogin" label:arial-label="Remember username">
<md-switch ng-model="app.creds.rememberLogin" label:arial-label="Remember username">
<var:string label:value="Remember username"/>
</md-switch>
</div>
@@ -117,7 +86,7 @@
<div layout="row" layout-align="end end" ng-cloak="ng-cloak">
<md-button class="sg-icon-button fg-sogoPaper-500"
label:aria-label="About"
ng-click="showAbout()">
ng-click="app.showAbout()">
<md-icon class="material-icons fg-sogoPaper-500">info</md-icon>
</md-button>
</div>
@@ -136,7 +105,7 @@
<!--<img class="full-image" const:alt="Inverse" rsrc:src="img/inverse.png"/>-->
</md-dialog-content>
<div class="md-actions">
<md-button ng-click="closeDialog()"><var:string label:value="Close"/></md-button>
<md-button ng-click="about.closeDialog()"><var:string label:value="Close"/></md-button>
</div>
</md-dialog>
</script>
+45 -29
View File
@@ -17,66 +17,83 @@
<md-input-container>
<label><var:string label:value="Account Name"/></label>
<input type="text" required="required"
ng-readonly="accountId == 0" ng-model="account.name"/>
ng-readonly="$AccountDialogController.accountId == 0"
ng-model="$AccountDialogController.account.name"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="Server Name"/></label>
<input type="text" required="required"
ng-readonly="accountId == 0" ng-model="account.serverName"/>
ng-readonly="$AccountDialogController.accountId == 0"
ng-model="$AccountDialogController.account.serverName"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="Port"/></label>
<input type="number" required="required" min="1" max="65535"
ng-readonly="accountId == 0" ng-model="account.port"/>
ng-readonly="$AccountDialogController.accountId == 0"
ng-model="$AccountDialogController.account.port"/>
</md-input-container>
<label><var:string label:value="Encryption"/></label>
<md-radio-group ng-model="account.encryption">
<md-radio-button ng-disabled="accountId == 0" value="none" class="md-primary"><var:string label:value="None"/></md-radio-button>
<md-radio-button ng-disabled="accountId == 0" value="ssl"><var:string label:value="SSL"/></md-radio-button>
<md-radio-button ng-disabled="accountId == 0" value="tls"><var:string label:value="TLS"/></md-radio-button>
<md-radio-group ng-model="$AccountDialogController.account.encryption">
<md-radio-button ng-disabled="$AccountDialogController.accountId == 0" value="none" class="md-primary"><var:string label:value="None"/></md-radio-button>
<md-radio-button ng-disabled="$AccountDialogController.accountId == 0" value="ssl"><var:string label:value="SSL"/></md-radio-button>
<md-radio-button ng-disabled="$AccountDialogController.accountId == 0" value="tls"><var:string label:value="TLS"/></md-radio-button>
</md-radio-group>
<md-input-container>
<label><var:string label:value="User Name"/></label>
<input type="text" required="required"
ng-readonly="accountId == 0" ng-model="account.userName"/>
ng-readonly="$AccountDialogController.accountId == 0"
ng-model="$AccountDialogController.account.userName"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="Password"/></label>
<input type="password" ng-readonly="accountId == 0"
ng-model="account.password"/>
<input type="password"
ng-readonly="$AccountDialogController.accountId == 0"
ng-model="$AccountDialogController.account.password"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="Full Name"/></label>
<input type="text" required="required"
ng-readonly="customFromIsReadonly()"
ng-model="account.identities[0].fullName"/>
ng-readonly="$AccountDialogController.customFromIsReadonly()"
ng-model="$AccountDialogController.account.identities[0].fullName"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="Email"/></label>
<input type="email" required="required"
ng-readonly="customFromIsReadonly()"
ng-model="account.identities[0].email"/>
ng-readonly="$AccountDialogController.customFromIsReadonly()"
ng-model="$AccountDialogController.account.identities[0].email"/>
</md-input-container>
<md-input-container>
<label><var:string label:value="Reply To Email"/></label>
<input type="email" ng-model="account.identities[0].replyTo"/>
<input type="email" ng-model="$AccountDialogController.account.identities[0].replyTo"/>
</md-input-container>
<!-- FIXME -->
<md-input-container>
<label><var:string label:value="Signature"/></label>
<input type="text" ng-model="account.identities[0].signature" />
</md-input-container>
<!-- To switch between a simple text editor and the CK/HTML editor, we use a ng-if and not
a ng-class as it doesn't get initialized by the ckEditor class directive -->
<md-input-container ng-if="$AccountDialogController.defaults.SOGoMailComposeMessageType == 'text'">
<label><var:string label:value="Signature"/> {{$AccountDialogController.defaults.SOGoMailComposeMessageType}}</label>
<textarea ng-model="$AccountDialogController.account.identities[0].signature"><!-- signature --></textarea>
</md-input-container>
<div class="pseudo-input-container"
ng-if="$AccountDialogController.defaults.SOGoMailComposeMessageType == 'html'">
<label class="pseudo-input-label"><var:string label:value="Signature"/> {{$AccountDialogController.defaults.LocaleCode}}</label>
<textarea class="ck-editor"
ck-locale="$AccountDialogController.defaults.LocaleCode"
ck-options="{ 'height': '70px',
'toolbar': [['Bold', 'Italic', '-', 'Link',
'Font','FontSize','-','TextColor',
'BGColor']] }"
ng-model="$AccountDialogController.account.identities[0].signature"><!-- signature --></textarea>
</div>
<md-radio-group ng-model="account.receipts.receiptAction">
<md-radio-group ng-model="$AccountDialogController.account.receipts.receiptAction">
<label><var:string label:value="When I receive a request for a return receipt"/></label>
<md-radio-button value="ignore"><var:string label:value="Never send a return receipt"/></md-radio-button>
<md-radio-button value="allow"><var:string label:value="Allow return receipts for some messages"/></md-radio-button>
@@ -84,7 +101,7 @@
<label>
<var:string label:value="If I'm not in the To or Cc of the message"/>
<md-select ng-model="account.receipts.receiptNonRecipientAction">
<md-select ng-model="$AccountDialogController.account.receipts.receiptNonRecipientAction">
<md-option const:value="ignore"><var:string label:value="Never send"/></md-option>
<md-option const:value="send"><var:string label:value="Always send"/></md-option>
<md-option const:value="ask"><var:string label:value="Ask me"/></md-option>
@@ -93,7 +110,7 @@
<label>
<var:string label:value="If the sender is outside my domain"/>
<md-select ng-model="account.receipts.receiptOutsideDomainAction">
<md-select ng-model="$AccountDialogController.account.receipts.receiptOutsideDomainAction">
<md-option const:value="ignore"><var:string label:value="Never send"/></md-option>
<md-option const:value="send"><var:string label:value="Always send"/></md-option>
<md-option const:value="ask"><var:string label:value="Ask me"/></md-option>
@@ -102,20 +119,19 @@
<label>
<var:string label:value="In all other cases"/>
<md-select ng-model="account.receipts.receiptAnyAction">
<md-select ng-model="$AccountDialogController.account.receipts.receiptAnyAction">
<md-option const:value="ignore"><var:string label:value="Never send"/></md-option>
<md-option const:value="send"><var:string label:value="Always send"/></md-option>
<md-option const:value="ask"><var:string label:value="Ask me"/></md-option>
</md-select>
</label>
<div class="md-actions" layout="row">
<md-button type="button" ng-click="cancel()">Cancel</md-button>
<md-button type="button" class="md-primary"
ng-disabled="accountForm.$invalid" ng-click="save()">Save</md-button>
</div>
</form>
</md-dialog-content>
<div class="md-actions">
<md-button type="button" ng-click="$AccountDialogController.cancel()"><var:string label:value="Cancel"/></md-button>
<md-button ng-disabled="$AccountDialogController.accountForm.$invalid" ng-click="$AccountDialogController.save()"><var:string label:value="Save"/></md-button>
</div>
</md-dialog>
</var:component>
@@ -8,7 +8,7 @@
xmlns:label="OGo:label"
className="UIxPageFrame"
title="title"
const:jsFiles="Common.js, Preferences.js, Preferences.services.js, Mailer.services.js, Contacts.services.js">
const:jsFiles="Common.js, Preferences.js, Preferences.services.js, Mailer.services.js, Contacts.services.js, vendor/ckeditor/ckeditor.js, vendor/ckeditor/ck.js">
<main class="view md-layout-fill" ui-view="preferences" layout="row"
ng-controller="navController"><!-- preferences --> </main>
@@ -660,7 +660,7 @@
ng-readonly="$index == 0"/>
</md-input-container>
<md-button class="sg-icon-button" type="button"
ng-click="app.editMailAccount($index)"
ng-click="app.editMailAccount($event, $index)"
layout="row"
layout-align="end center"
label:aria-label="Edit Account">
@@ -4,17 +4,17 @@
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label">
<md-dialog flex="60">
<md-dialog flex="60" flex-sm="100">
<form name="eventForm" ng-submit="editor.save(eventForm)">
<md-toolbar class="md-padding" ng-class="editor.component.getClassName('bg')">
<md-toolbar class="sg-padded" ng-class="editor.component.getClassName('bg')">
<div class="md-toolbar-tools">
<!-- summary -->
<md-icon ng-if="editor.component.classification == 'confidential'">visibility_off</md-icon>
<md-icon ng-if="editor.component.classification == 'private'">vpn_key</md-icon>
<md-input-container md-no-float="true">
<md-input-container>
<label><var:string label:value="Title"/></label>
<input type="text"
class="md-title"
label:placeholder="Title"
ng-model="editor.component.summary"/>
</md-input-container>
<md-button class="md-icon-button" ng-click="editor.cancel()">
@@ -22,15 +22,20 @@
</md-button>
</div>
</md-toolbar>
<!--<md-chips>
<md-chip ng-repeat="category in editor.component.categories">{{category}}</md-chip>
</md-chips>-->
<md-dialog-content>
<!-- location -->
<md-input-container>
<label><var:string label:value="Location"/></label>
<input type="text" ng-model="editor.component.location"/>
</md-input-container>
<!-- calendar -->
<md-input-container>
<label><var:string label:value="Calendar"/></label>
<md-select ng-model="editor.component.destinationCalendar">
<md-option ng-repeat="calendar in ::editor.calendars"
ng-value="calendar.id">{{calendar.name}}</md-option>
</md-select>
</md-input-container>
<!-- categories -->
<md-chips ng-model="editor.component.categories">
<md-autocomplete
@@ -41,14 +46,6 @@
<span md-highlight-text="editor.categories.searchText">{{category}}</span>
</md-autocomplete>
</md-chips>
<!-- calendar -->
<md-input-container>
<label><var:string label:value="Calendar"/></label>
<md-select ng-model="editor.component.destinationCalendar">
<md-option ng-repeat="calendar in ::editor.calendars"
ng-value="calendar.id">{{calendar.name}}</md-option>
</md-select>
</md-input-container>
<!-- classification -->
<md-radio-group layout="row" layout-align="space-around center"
ng-model="editor.component.classification">
@@ -63,8 +60,8 @@
</md-radio-button>
</md-radio-group>
<!-- priority -->
<div layout="row" layout-align="center center">
<div flex="20"><var:string label:value="Priority"/></div>
<div class="pseudo-input-container">
<label class="pseudo-input-label"><var:string label:value="Priority"/></label>
<md-slider class="md-flex"
md-discrete="true"
ng-model="editor.component.priority"
@@ -188,7 +185,7 @@
md-search-text="editor.searchText"
md-selected-item-change="editor.addAttendee(card)"
md-items="card in editor.cardFilter(editor.searchText)"
md-item-text="user.empty"
md-item-text="card.empty"
md-min-length="3"
md-delay="300"
md-no-cache="true"
@@ -144,7 +144,7 @@
class="md-flex"
md-input-name="delegatedTo"
md-search-text="editor.component.delegatedTo"
md-selected-item="editor.cardToAdd"
md-selected-item="cardToAdd"
md-items="card in editor.cardFilter(editor.component.delegatedTo)"
md-item-text="card.$$email"
md-min-length="3"
+26 -24
View File
@@ -18,28 +18,30 @@
<li><var:string label:value="Copy event to my calendar"/></li>
<li><var:string label:value="View Raw Source"/></li>
</ul>
</div>-->
<div layout="row" layout-align="center">
<h5>
<md-button
class="sg-icon-button"
label:aria-label="Previous Day"
var:date="prevDayQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
<var:string value="currentDayName" />
<md-button
class="sg-icon-button"
label:aria-label="Next Day"
var:date="nextDayQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
</h5>
</div>
<div id="calendarContent">
<var:component
className="UIxCalDayTable"
startDate="startDate"
const:CSSClass="dayOverview"
const:numberOfDays="1"
const:currentView="dayview"/>
</div>
</div>-->
<md-content>
<div layout="row" layout-align="center">
<h5>
<md-button
class="sg-icon-button"
label:aria-label="Previous Day"
var:date="prevDayQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
<var:string value="currentDayName" />
<md-button
class="sg-icon-button"
label:aria-label="Next Day"
var:date="nextDayQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
</h5>
</div>
<div id="calendarContent">
<var:component
className="UIxCalDayTable"
startDate="startDate"
const:CSSClass="dayOverview"
const:numberOfDays="1"
const:currentView="dayview"/>
</div>
</md-content>
</container>
+14 -14
View File
@@ -312,12 +312,12 @@
ng-controller="CalendarListController as list">
<md-toolbar layout="column" layout-align="space-between start" class="md-tall toolbar-main">
<div class="md-toolbar-tools md-toolbar-tools-top sg-padded" layout="row" layout-align="space-between start">
<!-- <var:component className="UIxTopnavToolbarTemplate" /> -->
<div class="sg-toolbar-group-2">
<var:component className="UIxTopnavToolbarTemplate" />
<!-- <div class="sg-toolbar-group-2">
<md-button class="sg-icon-button" label:aria-label="Search">
<md-icon>search</md-icon>
</md-button>
</div>
</div> -->
</div><!-- .md-toolbar-tools -->
<div class="md-toolbar-tools" layout="row" layout-align="space-between center">
<!-- sort/filter mode -->
@@ -534,24 +534,24 @@
<!-- Events list -->
<md-tab label:label="Events"
md-on-select="list.selectComponentType('events')">
<md-list>
<md-list-item class="md-clickable md-2-line"
<md-list class="sg-section-list">
<md-list-item class="md-2-line"
ng-repeat="event in list.component.$events"
ng-click="list.openEvent($event, event)">
<i class="md-avatar" ng-class="event.getClassName('bg')" ><!-- calendar color --></i>
<i class="md-tile-left" ng-class="event.getClassName('bg')" ><!-- calendar color --></i>
<div class="md-list-item-text">
<h3>{{event.c_title}}</h3>
<p>{{event.c_location}}</p>
<p class="md-secondary" layout="row">
{{event.formatted_startdate}}
<span class="sg-tile-icons">
<i class="sg-tile-icons">
<md-icon ng-show="event.c_iscycle">repeat</md-icon>
<md-icon ng-show="event.c_nextalarm">alarm</md-icon>
</span>
</i>
</p>
</div>
</md-list-item>
<md-list-item ng-if="list.component.$events.length == 0">
<md-list-item disabled="disabled" ng-if="list.component.$events.length == 0">
<p class="sg-md-caption"><var:string label:value="No events for selected criteria"/></p>
</md-list-item>
</md-list>
@@ -559,11 +559,11 @@
<!-- Tasks list -->
<md-tab label:label="Tasks"
md-on-select="list.selectComponentType('tasks')">
<md-list>
<md-list-item class="md-clickable md-2-line"
<md-list class="sg-section-list">
<md-list-item class="md-2-line"
ng-repeat="task in list.component.$tasks"
ng-click="list.openTask($event, task)">
<i class="md-avatar" ng-class="task.getClassName('bg')" ><!-- calendar color --></i>
<i class="md-tile-left" ng-class="task.getClassName('bg')" ><!-- calendar color --></i>
<div class="md-list-item-text">
<h3>{{task.c_title}}</h3>
<p class="md-secondary" layout="row">
@@ -575,7 +575,7 @@
</p>
</div>
</md-list-item>
<md-list-item ng-if="list.component.$tasks.length == 0">
<md-list-item disabled="disabled" ng-if="list.component.$tasks.length == 0">
<p class="sg-md-caption"><var:string label:value="No tasks for selected criteria"/></p>
</md-list-item>
</md-list>
@@ -587,7 +587,7 @@
<md-icon>add</md-icon>
</md-button>
</md-content>
<md-content class="view-detail sg-padded" ui-view="calendarView"><!-- calendar view --></md-content>
<div id="detailView" hide-sm="hide-sm" class="view-detail" layout="column" ui-view="calendarView"><!-- calendar view --></div>
</md-content>
</section>
</script>
+23 -19
View File
@@ -21,21 +21,22 @@
</ul>
</div>
<div layout="row" layout-align="center">
<h5>
<md-button
class="sg-icon-button"
label:aria-label="Previous Month"
var:date="prevMonthQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
<var:string value="monthNameOfThisMonth" />
<md-button
class="sg-icon-button"
label:aria-label="Next Month"
var:date="nextMonthQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
</h5>
</div>
<md-content>
<div layout="row" layout-align="center">
<h5>
<md-button
class="sg-icon-button"
label:aria-label="Previous Month"
var:date="prevMonthQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
<var:string value="monthNameOfThisMonth" />
<md-button
class="sg-icon-button"
label:aria-label="Next Month"
var:date="nextMonthQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
</h5>
</div>
<div class="monthView">
<div layout="row" layout-align="center center">
<var:foreach list="headerDaysToDisplay" item="currentTableDay">
@@ -55,13 +56,16 @@
var:day-number="currentDayNumber"
var:id="currentDayId">
<div layout="column" layout-fill="true">
<div class="sg-calendar-tile-header"><var:string value="dayHeaderNumber"/></div>
<sg-calendar-month-day
sg-blocks="calendar.blocks"
var:sg-day="currentTableDay.shortDateString"><!-- day's events --></sg-calendar-month-day></div>
<div class="sg-calendar-tile-header"><var:string value="dayHeaderNumber"/></div>
<sg-calendar-month-day
sg-blocks="calendar.blocks"
sg-click="list.openEvent(event, component)"
var:sg-day="currentTableDay.shortDateString"><!-- day's events --></sg-calendar-month-day>
</div>
</md-grid-tile>
</var:foreach>
</var:foreach>
</md-grid-list>
</div>
</md-content>
</container>
+25 -23
View File
@@ -6,27 +6,29 @@
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label">
<div layout="row" layout-align="center">
<h5>
<md-button
class="sg-icon-button"
label:aria-label="Previous Week"
var:date="prevWeekQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
<var:string value="currentWeekName" />
<md-button
class="sg-icon-button"
label:aria-label="Next Week"
var:date="nextWeekQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
</h5>
</div>
<div id="calendarContent">
<var:component
className="UIxCalDayTable"
startDate="startDate"
const:CSSClass="weekOverview"
const:numberOfDays="7"
const:currentView="weekview"/>
</div>
<md-content>
<div layout="row" layout-align="center">
<h5>
<md-button
class="sg-icon-button"
label:aria-label="Previous Week"
var:date="prevWeekQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_left</md-icon></md-button>
<var:string value="currentWeekName" />
<md-button
class="sg-icon-button"
label:aria-label="Next Week"
var:date="nextWeekQueryParameters.day"
ng-click="calendar.changeView($event)"><md-icon>chevron_right</md-icon></md-button>
</h5>
</div>
<div id="calendarContent">
<var:component
className="UIxCalDayTable"
startDate="startDate"
const:CSSClass="weekOverview"
const:numberOfDays="7"
const:currentView="weekview"/>
</div>
</md-content>
</container>
@@ -4,7 +4,7 @@
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label">
<div layout="row" layout-align="start center">
<div layout="row" layout-align="start center" layout-wrap="layout-wrap">
<md-input-container class="md-input-number">
<input type="number" label:aria-label="quantity" ng-model="editor.component.alarm.quantity"/>
</md-input-container>
@@ -4,17 +4,17 @@
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label">
<md-dialog flex="60">
<md-dialog flex="60" flex-sm="100">
<form name="eventForm" ng-submit="editor.save(eventForm)">
<md-toolbar class="md-padding" ng-class="editor.component.getClassName('bg')">
<div class="md-toolbar-tools">
<md-toolbar ng-class="editor.component.getClassName('bg')">
<div class="md-toolbar-tools sg-padded">
<!-- summary -->
<md-icon ng-if="editor.component.classification == 'confidential'">visibility_off</md-icon>
<md-icon ng-if="editor.component.classification == 'private'">vpn_key</md-icon>
<md-input-container md-no-float="true">
<md-input-container>
<label><var:string label:value="Title"/></label>
<input type="text"
class="md-title"
label:placeholder="Title"
ng-model="editor.component.summary"/>
</md-input-container>
<md-button class="md-icon-button" ng-click="editor.cancel()">
@@ -4,20 +4,20 @@
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label">
<md-dialog flex="40">
<md-toolbar class="md-padding" ng-class="viewer.component.getClassName('bg')">
<md-dialog flex="40" flex-md="60" flex-sm="100">
<md-toolbar class="md-padding" ng-class="editor.component.getClassName('bg')">
<div class="md-toolbar-tools">
<md-icon class="material-icons sg-icon-toolbar-bg">assignment_turned_in</md-icon>
<h2 class="md-flex">
<div class="sg-md-title md-flex">
<!-- classification -->
<md-icon ng-if="viewer.component.classification == 'confidential'">visibility_off</md-icon>
<md-icon ng-if="viewer.component.classification == 'private'">vpn_key</md-icon>
<md-icon ng-if="editor.component.classification == 'confidential'">visibility_off</md-icon>
<md-icon ng-if="editor.component.classification == 'private'">vpn_key</md-icon>
<!-- summary -->
{{viewer.component.summary}}
{{editor.component.summary}}
<!-- priority -->
<md-icon ng-repeat="i in viewer.component.priority | range">star</md-icon>
</h2>
<md-button class="md-icon-button" ng-click="viewer.close()">
<md-icon ng-repeat="i in editor.component.priority | range">star</md-icon>
</div>
<md-button class="md-icon-button" ng-click="editor.close()">
<md-icon aria-label="Close dialog">close</md-icon>
</md-button>
</div>
@@ -25,77 +25,77 @@
<md-dialog-content>
<md-list>
<!-- categories -->
<md-list-item ng-show="viewer.component.categories.length > 0">
<md-chips ng-model="viewer.component.categories" readonly="true">
<md-list-item ng-show="editor.component.categories.length > 0">
<md-chips class="sg-readonly" ng-model="editor.component.categories" readonly="true">
<md-chip-template>
<span>{{$chip}}</span>
</md-chip-template>
</md-chips>
</md-list-item>
<!-- location -->
<md-list-item ng-show="viewer.component.location">
<md-list-item ng-show="editor.component.location">
<md-icon>place</md-icon>
<p>{{viewer.component.location}}</p>
<p>{{editor.component.location}}</p>
</md-list-item>
<!-- calendar -->
<md-list-item>
<md-icon>event</md-icon>
<p>{{viewer.component.calendar}}</p>
<p>{{editor.component.calendar}}</p>
</md-list-item>
<!-- start/due dates -->
<md-list-item class="md-2-line">
<md-icon>access_time</md-icon>
<div layout="row" class="md-flex">
<div class="md-list-item-text" ng-show="viewer.component.startDate">
<div class="md-list-item-text" ng-show="editor.component.startDate">
<p><var:string label:value="Start"/></p>
<h3>
{{viewer.component.localizedStartDate}}
<span ng-hide="viewer.component.isAllDay"> {{viewer.component.localizedStartTime}}</span>
{{editor.component.localizedStartDate}}
<span ng-hide="editor.component.isAllDay"> {{editor.component.localizedStartTime}}</span>
</h3>
</div>
<div class="md-list-item-text" ng-show="viewer.component.dueDate">
<div class="md-list-item-text" ng-show="editor.component.dueDate">
<p><var:string label:value="Due Date"/></p>
<h3>
{{viewer.component.localizedDueDate}}
<span ng-hide="viewer.component.isAllDay">{{viewer.component.localizedDueTime}}</span>
{{editor.component.localizedDueDate}}
<span ng-hide="editor.component.isAllDay">{{editor.component.localizedDueTime}}</span>
</h3>
</div>
</div>
</md-list-item>
<!-- status -->
<md-list-item ng-show="viewer.component.status == 'completed'">
<md-list-item ng-show="editor.component.status == 'completed'">
<md-icon>check</md-icon>
<p>{{viewer.component.localizedCompletedDate}} {{viewer.component.localizedCompletedTime}}</p>
<p>{{editor.component.localizedCompletedDate}} {{editor.component.localizedCompletedTime}}</p>
</md-list-item>
<md-list-item ng-show="viewer.component.enablePercentComplete()">
<md-list-item ng-show="editor.component.enablePercentComplete()">
<md-icon>call_made</md-icon>
<p>{{viewer.component.percentComplete}} %</p>
<p>{{editor.component.percentComplete}} %</p>
</md-list-item>
<!-- attach urls -->
<md-list-item ng-show="viewer.component.attachUrls.length > 0">
<md-list-item ng-repeat="url in editor.component.attachUrls">
<md-icon>link</md-icon>
<p ng-repeat="url in viewer.component.attachUrls"><a ng-href="url.value">{{url.value}}</a></p>
<p><a ng-href="url.value">{{url.value}}</a></p>
</md-list-item>
<!-- comment -->
<md-list-item ng-show="viewer.component.comment">
<md-list-item ng-show="editor.component.comment">
<md-icon>mode_comment</md-icon>
<p>{{viewer.component.comment}}</p>
<p>{{editor.component.comment}}</p>
</md-list-item>
<!-- repeat -->
<md-list-item ng-show="viewer.component.repeat">
<md-list-item ng-show="editor.component.repeat">
<md-icon>repeat</md-icon>
<p><!-- viewer.component.repeat.toString() --></p>
<p><!-- editor.component.repeat.toString() --></p>
</md-list-item>
<!-- reminder -->
<md-list-item ng-show="viewer.component.$hasAlarm">
<md-list-item ng-show="editor.component.$hasAlarm">
<md-icon>alarm</md-icon>
<p><!-- viewer.component.alarm.toString() --></p>
<p><!-- editor.component.alarm.toString() --></p>
</md-list-item>
</md-list>
</md-dialog-content>
<!-- edit -->
<div class="md-actions">
<md-button ng-click="viewer.edit()">
<md-button ng-click="editor.edit()">
<var:string label:value="Edit"/>
</md-button>
</div>
+6 -7
View File
@@ -19,7 +19,7 @@
</title>
<meta name="hideFrame" var:content="hideFrame" />
<meta name="description" content="SOGo Web Interface" />
<meta name="author" content="SKYRIX Software AG/Inverse inc." />
<meta name="author" content="Inverse inc." />
<meta name="robots" content="stop" />
<meta name="build" var:content="buildDate" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
@@ -228,13 +228,12 @@
<var:string value="productLocalizableStrings" const:escapeHTML="NO" />
</script>
<script type="text/javascript" rsrc:src="js/vendor/lodash.min.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular-animate.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular-sanitize.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular-aria.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular.min.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular-animate.min.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular-sanitize.min.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular-aria.min.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular-material.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular-ui-router.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/Common/utils.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular-ui-router.min.js"><!-- space --></script>
<var:if condition="hasProductSpecificJavaScript">
<script type="text/javascript"
+10 -7
View File
@@ -4,7 +4,9 @@ include ../common.make
WEBSERVER_RESOURCE_DIRS = css fonts img js
build-static-files:
.DEFAULT_GOAL := all
dev:
npm install --production
@if [ ! -e angular-material/src ]; then \
git submodule init; \
@@ -17,9 +19,10 @@ build-static-files:
fi
grunt --stack build
all :: build-static-files
all:
@echo "The 'all' target does nothing. Use 'make dev' to generate static files and 'make install' to install them."
install ::
install:
@if [ -L "$(SOGO_WEBSERVERRESOURCESDIR)" ]; then \
echo "$(SOGO_WEBSERVERRESOURCESDIR) is a symbolic link (for development?). Installation skipped."; \
else \
@@ -27,13 +30,13 @@ install ::
cp -r $(WEBSERVER_RESOURCE_DIRS) $(SOGO_WEBSERVERRESOURCESDIR)/; \
fi
check ::
check:
clean ::
clean:
distclean :: clean
distclean: clean
uninstall ::
uninstall:
@if [ -L "$(SOGO_WEBSERVERRESOURCESDIR)" ]; then \
echo "$(SOGO_WEBSERVERRESOURCESDIR) is a symbolic link (for development?). Uninstallation skipped."; \
else \
+6 -5
View File
@@ -1,14 +1,15 @@
module.exports = function(grunt) {
var js_files = {
'js/Common.js': ['js/Common/Common.app.js', 'js/Common/*.filter.js', 'js/Common/*Controller.js', 'js/Common/*.service.js', 'js/Common/*.directive.js'],
'js/Common.js': ['js/Common/Common.app.js', 'js/Common/*.filter.js', 'js/Common/*Controller.js', 'js/Common/*.service.js', 'js/Common/*.directive.js', 'js/Common/utils.js'],
'js/Main.js': ['js/Main/Main.app.js'],
'js/Scheduler.services.js': ['js/Scheduler/*.service.js'],
'js/Scheduler.js': ['js/Scheduler.app.js', 'js/Scheduler/*Controller.js', 'js/Scheduler/*.directive.js'],
'js/Scheduler.js': ['js/Scheduler/Scheduler.app.js', 'js/Scheduler/*Controller.js', 'js/Scheduler/*.directive.js'],
'js/Contacts.services.js': ['js/Contacts/*.service.js'],
'js/Contacts.js': ['js/Contacts.app.js', 'js/Contacts/*Controller.js', 'js/Contacts/*.directive.js'],
'js/Contacts.js': ['js/Contacts/Contacts.app.js', 'js/Contacts/*Controller.js', 'js/Contacts/*.directive.js'],
'js/Mailer.services.js': ['js/Mailer/*.service.js'],
'js/Mailer.js': ['js/Mailer.app.js', 'js/Mailer/*Controller.js', 'js/Mailer/*.directive.js'],
'js/Mailer.js': ['js/Mailer/Mailer.app.js', 'js/Mailer/*Controller.js', 'js/Mailer/*.directive.js'],
'js/Preferences.services.js': ['js/Preferences/*.service.js'],
'js/Preferences.js': ['js/Preferences.app.js', 'js/Preferences/*Controller.js']
'js/Preferences.js': ['js/Preferences/Preferences.app.js', 'js/Preferences/*Controller.js']
};
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../scss/components/_palette.scss","../scss/core/reset.scss","styles.css","../scss/core/angular.scss","../scss/styles.scss","../angular-material/src/core/style/mixins.scss","../angular-material/src/core/style/structure.scss","../scss/core/variables.scss","../scss/core/structure.scss","../angular-material/src/core/style/layout.scss","../scss/core/layout.scss","../bower_components/breakpoint-sass/stylesheets/_breakpoint.scss","../angular-material/src/core/style/typography.scss","../scss/core/typography.scss","../scss/core/_functions.scss","../angular-material/src/components/autocomplete/autocomplete.scss","../scss/components/backdrop/_extends.scss","../angular-material/src/components/backdrop/backdrop.scss","../scss/components/backdrop/backdrop.scss","../scss/components/bottomSheet/_extends.scss","../angular-material/src/components/bottomSheet/bottomSheet.scss","../scss/components/bottomSheet/bottomSheet.scss","../scss/components/button/_extends.scss","../angular-material/src/components/button/button.scss","../scss/components/button/button.scss","../scss/components/card/_extends.scss","../angular-material/src/components/card/card.scss","../scss/components/card/card.scss","../scss/components/checkbox/_extends.scss","../angular-material/src/components/checkbox/checkbox.scss","../scss/components/checkbox/checkbox.scss","../scss/components/chips/_extends.scss","../angular-material/src/components/chips/chips.scss","../scss/components/chips/chips.scss","../scss/components/content/_extends.scss","../angular-material/src/components/content/content.scss","../scss/components/content/content.scss","../scss/components/dialog/_extends.scss","../angular-material/src/components/dialog/dialog.scss","../scss/components/dialog/dialog.scss","../scss/components/divider/_extends.scss","../angular-material/src/components/divider/divider.scss","../scss/components/fabSpeedDial/_extends.scss","../angular-material/src/components/fabSpeedDial/fabSpeedDial.scss","../angular-material/src/components/gridList/gridList.scss","../scss/components/gridList/gridList.scss","../scss/components/icon/_extends.scss","../angular-material/src/components/icon/icon.scss","../scss/components/icon/icon.scss","../scss/components/input/_extends.scss","../angular-material/src/components/input/input.scss","../scss/components/input/input.scss","../scss/components/list/_extends.scss","../angular-material/src/components/list/list.scss","../scss/components/list/list.scss","../scss/components/menu/_extends.scss","../angular-material/src/components/menu/menu.scss","../scss/components/progressLinear/_extends.scss","../angular-material/src/components/progressLinear/progressLinear.scss","../scss/components/radioButton/_extends.scss","../angular-material/src/components/radioButton/radio-button.scss","../scss/components/select/_extends.scss","../angular-material/src/components/select/select.scss","../scss/components/select/select.scss","../scss/components/sidenav/_extends.scss","../angular-material/src/components/sidenav/sidenav.scss","../scss/components/sidenav/sidenav.scss","../scss/components/slider/_extends.scss","../angular-material/src/components/slider/slider.scss","../scss/components/sticky/_extends.scss","../angular-material/src/components/sticky/sticky.scss","../scss/components/subheader/_extends.scss","../angular-material/src/components/subheader/subheader.scss","../scss/components/subheader/subheader.scss","../scss/components/switch/_extends.scss","../angular-material/src/components/switch/switch.scss","../scss/components/tabs/_extends.scss","../angular-material/src/components/tabs/tabs.scss","../scss/components/toast/_extends.scss","../angular-material/src/components/toast/toast.scss","../scss/components/toolbar/_extends.scss","../angular-material/src/components/toolbar/toolbar.scss","../scss/components/toolbar/toolbar.scss","../scss/components/tooltip/_extends.scss","../angular-material/src/components/tooltip/tooltip.scss","../scss/components/virtualRepeat/_extends.scss","../angular-material/src/components/virtualRepeat/virtualRepeater.scss","../scss/components/virtualRepeat/virtualRepeat.scss","../scss/components/whiteframe/_extends.scss","../angular-material/src/components/whiteframe/whiteframe.scss","../scss/components/whiteframe/whiteframe.scss","../scss/components/pseudo-input/pseudo-input.scss","../scss/views/LoginUI.scss","../scss/views/MailerUI.scss","../scss/views/ContactsUI.scss","../scss/views/MessageEditorUI.scss","../scss/views/SchedulerUI.scss","../scss/views/_view.scss","../scss/core/base_styles/_base_style.scss","../scss/_devtools.scss"],"names":[],"mappings":"AAEA;;;;;GAKG;AAqYiC;EAE9B,eAzSO,EAwSP;;AAEA;EAEA,0BA5SO,EA2SP;;AAJ8B;EAE9B,eAxSO,EAuSP;;AAEA;EAEA,0BA3SO,EA0SP;;AAJ8B;EAE9B,eAvSO,EAsSP;;AAEA;EAEA,0BA1SO,EAySP;;AAJ8B;EAE9B,eAtSO,EAqSP;;AAEA;EAEA,0BAzSO,EAwSP;;AAJ8B;EAE9B,eArSO,EAoSP;;AAEA;EAEA,0BAxSO,EAuSP;;AAJ8B;EAE9B,eApSO,EAmSP;;AAEA;EAEA,0BAvSO,EAsSP;;AAJ8B;EAE9B,eAnSO,EAkSP;;AAEA;EAEA,0BAtSO,EAqSP;;AAJ8Line truncated
+3
View File
@@ -0,0 +1,3 @@
function l(){var key=arguments[0],value=key;labels[key]?value=labels[key]:clabels[key]&&(value=clabels[key]);for(var i=1,j=0;i<arguments.length;i++,j++)value=value.replace("%{"+j+"}",arguments[i]);return value}!function(){"use strict";function configure($mdThemingProvider){$mdThemingProvider.definePalette("sogo-green",{50:"eaf5e9",100:"cbe5c8",200:"aad6a5",300:"88c781",400:"66b86a",500:"56b04c",600:"4da143",700:"388e3c",800:"367d2e",900:"225e1b",A100:"b9f6ca",A200:"69f0ae",A400:"00e676",A700:"00c853",contrastDefaultColor:"dark",contrastDarkColors:"50 100 200",contrastLightColors:"300 400 500 600 700 800 900"}),$mdThemingProvider.definePalette("sogo-blue",{50:"f0faf9",100:"e1f5f3",200:"ceebe8",300:"bfe0dd",400:"b2d6d3",500:"a1ccc8",600:"8ebfbb",700:"7db3b0",800:"639997",900:"4d8080",A100:"d4f7fa",A200:"c3f5fa",A400:"53e3f0",A700:"00b0c0",contrastDefaultColor:"light",contrastDarkColors:["50","100","200"],contrastLightColors:["300","400","500","600","700","800","900","A100","A200","A400","A700"]}),$mdThemingProvider.definePalette("sogo-paper",{50:"fcf7f8",100:"f7f1dc",200:"ede5ca",300:"e6d8ba",400:"e2d2a3",500:"d6c48d",600:"baa870",700:"857545",800:"524517",900:"433809",1000:"000000",A100:"ffffff",A200:"eeeeee",A400:"bdbdbd",A700:"616161",contrastDefaultColor:"dark",contrastLightColors:"800 900"}),$mdThemingProvider.theme("default").primaryPalette("sogo-blue",{"default":"300","hue-1":"100","hue-2":"400","hue-3":"A700"}).accentPalette("sogo-green",{"default":"500","hue-1":"200","hue-2":"300","hue-3":"A700"}).backgroundPalette("sogo-paper",{"default":"100","hue-1":"200","hue-2":"50","hue-3":"500"})}angular.module("SOGo.Common",["ngMaterial"]).value("sgSettings",{baseURL:function(){return ApplicationBaseURL||null},activeUser:function(param){var settings={login:UserLogin||null,identification:UserIdentification||null,language:UserLanguage||null,folderURL:UserFolderURL||null,isSuperUser:IsSuperUser||null};return param?settings[param]:settings}}).constant("sgColors",{selection:["#FFFFFF","#330033","#C0C0C0","#999999","#666666","#333333","#000000","#FFCCCC","#FF6666","#FF0000","#CC0000","#990000","#660000","#330000","#FFCC99","#FF9966","#FF9900","#FF6600","#CC6600","#993300","#663300","#FFFF99","#FFFF66","#FFCC66","#FFCC33","#CC9933","#996633","#663333","#FFFFCC","#FFFF33","#FFFF00","#FFCC00","#999900","#666600","#333300","#CCCCCC","#66FF99","#33FF33","#33CC00","#009900","#006600","#003300","#99FFFF","#33FFFF","#66CCCC","#00CCCC","#339999","#336666","#003333","#CCFFFF","#66FFFF","#33CCFF","#3366FF","#3333FF","#000099","#000066","#CCCCFF","#9999FF","#6666CC","#6633FF","#6600CC","#333399","#330099","#FFCCFF","#FF99FF","#CC66CC","#CC33CC","#993399","#663366","#99FF99"]}).constant("sgConstant",{sm:"(max-width: 600px)","gt-sm":"(min-width: 600px)",md:"(min-width: 600px) and (max-width: 1024px)","gt-md":"(min-width: 1025px)",lg:"(min-width: 1024px) and (max-width: 1280px)","gt-lg":"(min-width: 1280px)"}).config(configure),configure.$inject=["$mdThemingProvider"]}(),function(){"use strict";function decodeUri($window){return $window.decodeURIComponent}decodeUri.$inject=["$window"],angular.module("SOGo.Common").filter("decodeUri",decodeUri)}(),function(){"use strict";function encodeUri($window){return $window.encodeURIComponent}encodeUri.$inject=["$window"],angular.module("SOGo.Common").filter("encodeUri",encodeUri)}(),function(){"use strict";function loc(){return l}angular.module("SOGo.Common").filter("loc",loc)}(),function(){"use strict";function range(){return function(n){for(var res=[],i=0;i<parseInt(n);i++)res.push(i);return res}}angular.module("SOGo.Common").filter("range",range)}(),function(){"use strict";function AclController($mdDialog,Dialog,usersWithACL,User,folder){function userFilter($query){return User.$filter($query,folder.$acl.users)}function closeModal(){folder.$acl.$resetUsersRights(),$mdDialog.hide()}function saveModal(){folder.$acl.$saveUsersRights().then(function(){$mdDialog.hide()},function(data,status){Dialog.alert(l("Warning"),l("An error occured please try again."))})}function confirmChange(user){var confirmation=user.$confirmRights();confirmation&&(vm.confirmation.showing=!0,vm.confirmation.message=confirmation)}function removeUser(user){folder.$acl.$removeUser(user.uid)["catch"](function(data,status){Dialog.alert(l("Warning"),l("An error occured please try again."))})}function addUser(data){data&&folder.$acl.$addUser(data).then(function(){vm.userToAdd="",vm.searchText=""},function(error){Dialog.alert(l("Warning"),error)})}function selectUser(user){vm.selectedUser==user?vm.selectedUser=null:(vm.selectedUser=user,vm.selectedUser.$rights())}var vm=this;vm.users=usersWithACL,vm.folder=folder,vm.selectedUser=null,vm.userToAdd="",vm.searchText="",vm.userFilter=userFilter,vm.closeModal=closeModal,vm.saveModal=saveModal,vm.confirmChange=confirmChange,vm.removeUser=removeUser,vm.addUser=addUser,vm.selectUser=selectUser,vm.confirmation={showing:!1,message:""}}AclController.$inject=["$mdDialog","Dialog","usersLine truncated
}),ensureInitRunsOnce()}}),toggleClass=function(){var tile=angular.element(this),day=tile.attr("value");tile.toggleClass("sg-active"),toggle(day)},i=0;i<tiles.length;i++)tile=angular.element(tiles[i]),tile.addClass("iconButton"),tile.find("figure").addClass("md-icon"),tile.on("click",toggleClass)}return{restrict:"A",link:link}}sgToggleGrid.$inject=["$parse"],angular.module("SOGo.Common").directive("sgToggleGrid",sgToggleGrid)}(),String.prototype.endsWith=function(suffix){return-1!==this.indexOf(suffix,this.length-suffix.length)},String.prototype.startsWith=function(pattern,position){return position=angular.isNumber(position)?position:0,this.lastIndexOf(pattern,position)===position},String.prototype._base64_keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",String.prototype.base64encode=function(){for(var chr1,chr2,chr3,enc1,enc2,enc3,enc4,output="",i=0,input=this.utf8encode();i<input.length;)chr1=input.charCodeAt(i++),chr2=input.charCodeAt(i++),chr3=input.charCodeAt(i++),enc1=chr1>>2,enc2=(3&chr1)<<4|chr2>>4,enc3=(15&chr2)<<2|chr3>>6,enc4=63&chr3,isNaN(chr2)?enc3=enc4=64:isNaN(chr3)&&(enc4=64),output=output+this._base64_keyStr.charAt(enc1)+this._base64_keyStr.charAt(enc2)+this._base64_keyStr.charAt(enc3)+this._base64_keyStr.charAt(enc4);return output},String.prototype.base64decode=function(){for(var chr1,chr2,chr3,enc1,enc2,enc3,enc4,output="",i=0,input=""+this;i<input.length;)enc1=this._base64_keyStr.indexOf(input.charAt(i++)),enc2=this._base64_keyStr.indexOf(input.charAt(i++)),enc3=this._base64_keyStr.indexOf(input.charAt(i++)),enc4=this._base64_keyStr.indexOf(input.charAt(i++)),chr1=enc1<<2|enc2>>4,chr2=(15&enc2)<<4|enc3>>2,chr3=(3&enc3)<<6|enc4,output+=String.fromCharCode(chr1),64!=enc3&&(output+=String.fromCharCode(chr2)),64!=enc4&&(output+=String.fromCharCode(chr3));return output},String.prototype.md5=function(){if(this.length){var md5=function(s){function L(k,d){return k<<d|k>>>32-d}function K(G,k){var I,d,F,H,x;return F=2147483648&G,H=2147483648&k,I=1073741824&G,d=1073741824&k,x=(1073741823&G)+(1073741823&k),I&d?2147483648^x^F^H:I|d?1073741824&x?3221225472^x^F^H:1073741824^x^F^H:x^F^H}function r(d,F,k){return d&F|~d&k}function q(d,F,k){return d&k|F&~k}function p(d,F,k){return d^F^k}function n(d,F,k){return F^(d|~k)}function u(G,F,aa,Z,k,H,I){return G=K(G,K(K(r(F,aa,Z),k),I)),K(L(G,H),F)}function f(G,F,aa,Z,k,H,I){return G=K(G,K(K(q(F,aa,Z),k),I)),K(L(G,H),F)}function D(G,F,aa,Z,k,H,I){return G=K(G,K(K(p(F,aa,Z),k),I)),K(L(G,H),F)}function t(G,F,aa,Z,k,H,I){return G=K(G,K(K(n(F,aa,Z),k),I)),K(L(G,H),F)}function e(G){for(var Z,F=G.length,x=F+8,k=(x-x%64)/64,I=16*(k+1),aa=Array(I-1),d=0,H=0;F>H;)Z=(H-H%4)/4,d=H%4*8,aa[Z]=aa[Z]|G.charCodeAt(H)<<d,H++;return Z=(H-H%4)/4,d=H%4*8,aa[Z]=aa[Z]|128<<d,aa[I-2]=F<<3,aa[I-1]=F>>>29,aa}function B(x){var G,d,k="",F="";for(d=0;3>=d;d++)G=x>>>8*d&255,F="0"+G.toString(16),k+=F.substr(F.length-2,2);return k}function J(k){k=k.replace(/rn/g,"n");for(var d="",F=0;F<k.length;F++){var x=k.charCodeAt(F);128>x?d+=String.fromCharCode(x):x>127&&2048>x?(d+=String.fromCharCode(x>>6|192),d+=String.fromCharCode(63&x|128)):(d+=String.fromCharCode(x>>12|224),d+=String.fromCharCode(x>>6&63|128),d+=String.fromCharCode(63&x|128))}return d}var P,h,E,v,g,Y,X,W,V,C=Array(),S=7,Q=12,N=17,M=22,A=5,z=9,y=14,w=20,o=4,m=11,l=16,j=23,U=6,T=10,R=15,O=21;for(s=J(s),C=e(s),Y=1732584193,X=4023233417,W=2562383102,V=271733878,P=0;P<C.length;P+=16)h=Y,E=X,v=W,g=V,Y=u(Y,X,W,V,C[P+0],S,3614090360),V=u(V,Y,X,W,C[P+1],Q,3905402710),W=u(W,V,Y,X,C[P+2],N,606105819),X=u(X,W,V,Y,C[P+3],M,3250441966),Y=u(Y,X,W,V,C[P+4],S,4118548399),V=u(V,Y,X,W,C[P+5],Q,1200080426),W=u(W,V,Y,X,C[P+6],N,2821735955),X=u(X,W,V,Y,C[P+7],M,4249261313),Y=u(Y,X,W,V,C[P+8],S,1770035416),V=u(V,Y,X,W,C[P+9],Q,2336552879),W=u(W,V,Y,X,C[P+10],N,4294925233),X=u(X,W,V,Y,C[P+11],M,2304563134),Y=u(Y,X,W,V,C[P+12],S,1804603682),V=u(V,Y,X,W,C[P+13],Q,4254626195),W=u(W,V,Y,X,C[P+14],N,2792965006),X=u(X,W,V,Y,C[P+15],M,1236535329),Y=f(Y,X,W,V,C[P+1],A,4129170786),V=f(V,Y,X,W,C[P+6],z,3225465664),W=f(W,V,Y,X,C[P+11],y,643717713),X=f(X,W,V,Y,C[P+0],w,3921069994),Y=f(Y,X,W,V,C[P+5],A,3593408605),V=f(V,Y,X,W,C[P+10],z,38016083),W=f(W,V,Y,X,C[P+15],y,3634488961),X=f(X,W,V,Y,C[P+4],w,3889429448),Y=f(Y,X,W,V,C[P+9],A,568446438),V=f(V,Y,X,W,C[P+14],z,3275163606),W=f(W,V,Y,X,C[P+3],y,4107603335),X=f(X,W,V,Y,C[P+8],w,1163531501),Y=f(Y,X,W,V,C[P+13],A,2850285829),V=f(V,Y,X,W,C[P+2],z,4243563512),W=f(W,V,Y,X,C[P+7],y,1735328473),X=f(X,W,V,Y,C[P+12],w,2368359562),Y=D(Y,X,W,V,C[P+5],o,4294588738),V=D(V,Y,X,W,C[P+8],m,2272392833),W=D(W,V,Y,X,C[P+11],l,1839030562),X=D(X,W,V,Y,C[P+14],j,4259657740),Y=D(Y,X,W,V,C[P+1],o,2763975236),V=D(V,Y,X,W,C[P+4],m,1272893353),W=D(W,V,Y,X,C[P+7],l,4139469664),X=D(X,W,V,Y,C[P+10],j,3200236656),Y=D(Y,X,W,V,C[P+13],o,681279174),V=D(V,Y,X,W,C[P+0],m,3936430074),W=D(W,V,Y,X,C[P+3],l,3572445317),X=D(X,W,V,Y,C[P+6],j,76029189),Y=D(Y,X,W,V,C[P+9],o,3654602809),V=D(V,Y,X,W,C[P+12],m,3873151461),W=D(W,V,Y,X,C[P+Line truncated
//# sourceMappingURL=Common.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Common.js","sources":["Common/utils.js","Common/Common.app.js","Common/decodeUri.filter.js","Common/encodeUri.filter.js","Common/loc.filter.js","Common/range.filter.js","Common/AclController.js","Common/navController.js","Common/Acl.service.js","Common/Alarm.service.js","Common/Authentication.service.js","Common/Dialog.service.js","Common/Gravatar.service.js","Common/Resource.service.js","Common/User.service.js","Common/sgFocus.service.js","Common/sgAvatarImage.directive.js","Common/sgColorPicker.directive.js","Common/sgCompile.directive.js","Common/sgEnter.directive.js","Common/sgEscape.directive.js","Common/sgFocus.directive.js","Common/sgFolderStylesheet.directive.js","Common/sgSearch.directive.js","Common/sgSubscribe.directive.js","Common/sgToggleGrid.directive.js"],"names":["l","key","arguments","value","labels","clabels","i","j","length","replace","configure","$mdThemingProvider","definePalette","50","100","200","300","400","500","600","700","800","900","A100","A200","A400","A700","contrastDefaultColor","contrastDarkColors","contrastLightColors","1000","theme","primaryPalette","default","hue-1","hue-2","hue-3","accentPalette","backgroundPalette","angular","module","baseURL","ApplicationBaseURL","activeUser","param","settings","login","UserLogin","identification","UserIdentification","language","UserLanguage","folderURL","UserFolderURL","isSuperUser","IsSuperUser","constant","selection","sm","gt-sm","md","gt-md","lg","gt-lg","config","$inject","decodeUri","$window","decodeURIComponent","filter","encodeUri","encodeURIComponent","loc","range","n","res","parseInt","push","AclController","$mdDialog","Dialog","usersWithACL","User","folder","userFilter","$query","$filter","$acl","users","closeModal","$resetUsersRights","hide","saveModal","$saveUsersRights","then","data","status","alert","confirmChange","user","confirmation","$confirmRights","vm","showing","message","removeUser","$removeUser","uid","addUser","$addUser","userToAdd","searchText","error","selectUser","selectedUser","$rights","this","controller","navController","$scope","$timeout","$interval","$http","$mdSidenav","$mdBottomSheet","$mdMedia","$log","sgConstant","sgSettings","Alarm","currentDay","window","get","success","secondsBeforeTomorrow","toggleLeft","toggle","debug","toggleRight","openBottomSheet","show","parent","element","document","getElementById","templateUrl","toggleDetailView","detail","toggleClass","$watch","newVal","isGtMedium","getAlarms","Acl","folderId","factory","$q","Settings","Resource","extend","$$resource","$User","prototype","$users","_this","deferred","defer","resolve","promise","fetch","response","forEach","canSubscribeUser","isSubscribed","wasSubscribed","bind","_","indexOf","pluck","userClass","isGroup","reject","splice","$resetRights","deferredSave","deferredSubscribe","action","$rightsAreDirty","$omit","save","$shadowRights","copy","rights","uids","join","all","currentAlarm","AlarmService","$mdToast","$toast","now","Date","browserTime","Math","floor","getTime","alarms","sort","a","b","x","y","next","pop","utc","url","alarmTime","delay","f","showAlarm","cancel","AlarmController","scope","reminder","ok","position","hideDelay","template","locals","Authentication","readCookie","name","foundCookie","prefix","pairs","currentPair","start","cookie","split","charAt","substr","readLoginCookie","loginValues","base64decode","redirectUrl","username","domain","userName","address","baseAddress","altBaseAddress","parts","hostpart","protocol","newAddress","location","href","startsWith","endsWith","getService","passwordPolicyConfig","service","d","password","rememberLogin","loginSuffix","method","loginCookie","expire","grace","msg","perr","LDAPPasswordPolicyError","PolicyNoError","PolicyAccountLocked","changePassword","newPassword","PolicyPasswordModNotAllowed","PolicyInsufficientPasswordQuality","PolicyPasswordTooShort","PolicyPasswordTooYoung","PolicyPasswordInHistory","formatted","PolicyPasswordUnknown","PolicyPasswordSystemUnknown","$get","PolicyPasswordChangeUnsupported","PolicyPasswordExpired","PolicyChangeAfterReset","PolicyMustSupplyOldPassword","provider","DialogService","$modal","title","content","confirm","options","prompt","label","PromptDialogController","o","body","clickOutsideToClose","escapeToClose","inputType","Gravatar","email","size","hash","s","substring","md5","path","_http","_q","_path","_activeUser","$factory","userResource","compact","escape","params","flatten","newguid","create","post","id","newValue","remove","userData","init","$gravatar","search","excludedUsers","when","results","index","compareUids","find","each","isUndefined","$$shortFormat","$shortFormat","$$image","image","c_email","empty","fullname","cn","no_email","$isAnonymous","$isSpecial","$confirmation","some","values","isEqual","zero","map","keys","isString","$folders","type","$$folders","folders","toString","sgFocus","$rootScope","$broadcast","sgAvatarImage","restrict","src","bindToController","controllerAs","sgAvatarImageContLine truncated
@@ -48,7 +48,7 @@
else {
return Acl.$$resource.fetch(this.folderId, 'acls').then(function(response) {
_this.users = [];
// console.debug(JSON.stringify(users, undefined, 2));
//console.debug(JSON.stringify(users, undefined, 2));
angular.forEach(response.users, function(data) {
user = new Acl.$User(data);
user.canSubscribeUser = user.isSubscribed;
@@ -78,7 +78,7 @@
}
}
angular
.module('SOGo.Common')
.controller('AclController', AclController);
angular
.module('SOGo.Common')
.controller('AclController', AclController);
})();
@@ -26,9 +26,6 @@
// TODO: convert to a Factory recipe?
.provider('Authentication', Authentication);
/**
* @ngInject
*/
function Authentication() {
function readCookie(name) {
var foundCookie, prefix, pairs, i, currentPair, start;
@@ -91,9 +88,11 @@
this.$get = getService;
/**
* @ngInject
*/
getService.$inject = ['$q', '$http', 'passwordPolicyConfig'];
function getService($q, $http, passwordPolicyConfig) {
var _this = this, service;
service = {
@@ -31,12 +31,12 @@
* @param {string} content
* @returns a promise that resolves if the user has clicked on the 'OK' button
*/
Dialog.confirm = function(title, content) {
Dialog.confirm = function(title, content, options) {
var confirm = this.$modal.confirm()
.title(title)
.content(content)
.ok(l('OK'))
.cancel(l('Cancel'));
.ok((options && options.ok)? options.ok : l('OK'))
.cancel((options && options.cancel)? options.cancel : l('Cancel'));
return this.$modal.show(confirm);
};
@@ -12,10 +12,16 @@
*/
function Gravatar() {
return function(email, size) {
var hash, s = size;
var x, y, hash, s = size;
if (!email) {
return '';
}
x = email.indexOf('<');
if (x >= 0) {
y = email.indexOf('>', x);
if (y > x)
email = email.substring(x+1,y);
}
if (!size) {
s = 48; // default to 48 pixels
}
@@ -45,6 +45,7 @@
*/
User.$filter = function(search, excludedUsers) {
var param = {search: search};
var _this = this;
if (!search) {
// No query specified
@@ -60,7 +61,7 @@
return User.$$resource.fetch(null, 'usersSearch', param).then(function(response) {
var results, index, user,
compareUids = function(data) {
return this.uid == data.uid;
return _this.uid == data.uid;
};
if (excludedUsers) {
// Remove excluded users from response
+5 -7
View File
@@ -80,7 +80,7 @@ String.prototype.md5 = function() {
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
};
String.prototype.asDate = function () {
var newDate;
@@ -129,7 +129,7 @@ String.prototype.formatTime = function(hours, minutes) {
};
Date.prototype.daysUpTo = function(otherDate) {
var days = new Array();
var days = [];
var day1 = this.getTime();
var day2 = otherDate.getTime();
@@ -155,10 +155,8 @@ String.prototype.isValidEmail = function() {
};
String.prototype.asCSSIdentifier = function() {
var characters = [ '_' , '\\.', '#' , '@' , '\\*', ':' , ',' , ' '
, "'", '&', '\\+' ];
var escapeds = [ '_U_', '_D_', '_H_', '_A_', '_S_', '_C_', '_CO_',
'_SP_', '_SQ_', '_AM_', '_P_' ];
var characters = [ '_' , '\\.', '#' , '@' , '\\*', ':' , ',' , ' ', "'", '&', '\\+' ];
var escapeds = [ '_U_', '_D_', '_H_', '_A_', '_S_', '_C_', '_CO_', '_SP_', '_SQ_', '_AM_', '_P_' ];
var newString = this;
for (var i = 0; i < characters.length; i++) {
@@ -231,7 +229,7 @@ Date.prototype.beginOfDay = function() {
beginOfDay.setMilliseconds(0);
return beginOfDay;
}
};
Date.prototype.beginOfWeek = function() {
var offset = firstDayOfWeek - this.getDay();
+2
View File
@@ -0,0 +1,2 @@
!function(){"use strict";function configure($stateProvider,$urlRouterProvider){$stateProvider.state("app",{url:"/addressbooks","abstract":!0,views:{addressbooks:{templateUrl:"UIxContactFoldersView",controller:"AddressBooksController",controllerAs:"app"}},resolve:{stateAddressbooks:stateAddressbooks}}).state("app.addressbook",{url:"/:addressbookId",views:{addressbook:{templateUrl:"addressbook",controller:"AddressBookController",controllerAs:"addressbook"}},resolve:{stateAddressbook:stateAddressbook}}).state("app.addressbook.new",{url:"/{contactType:(?:card|list)}/new",views:{card:{templateUrl:"UIxContactEditorTemplate",controller:"CardController",controllerAs:"editor"}},resolve:{stateCard:stateNewCard}}).state("app.addressbook.card",{url:"/:cardId","abstract":!0,views:{card:{template:"<ui-view/>"}},resolve:{stateCard:stateCard}}).state("app.addressbook.card.view",{url:"/view",views:{"card@app.addressbook":{templateUrl:"UIxContactViewTemplate",controller:"CardController",controllerAs:"editor"}}}).state("app.addressbook.card.editor",{url:"/edit",views:{"card@app.addressbook":{templateUrl:"UIxContactEditorTemplate",controller:"CardController",controllerAs:"editor"}}}),$urlRouterProvider.otherwise("/addressbooks/personal")}function stateAddressbooks(AddressBook){return AddressBook.$findAll(window.contactFolders)}function stateAddressbook($stateParams,AddressBook){return AddressBook.$find($stateParams.addressbookId).$futureAddressBookData}function stateNewCard($stateParams,stateAddressbook,Card){var tag="v"+$stateParams.contactType,card=new Card({pid:$stateParams.addressbookId,c_component:tag});return stateAddressbook.selectedCard=!0,card}function stateCard($stateParams,stateAddressbook){return stateAddressbook.selectedCard=$stateParams.cardId,stateAddressbook.$getCard($stateParams.cardId)}function runBlock($rootScope){$rootScope.$on("$routeChangeError",function(event,current,previous,rejection){console.error(event,current,previous,rejection)})}angular.module("SOGo.ContactsUI",["ngSanitize","ui.router","SOGo.Common","SOGo.PreferencesUI"]).config(configure).run(runBlock),configure.$inject=["$stateProvider","$urlRouterProvider"],stateAddressbooks.$inject=["AddressBook"],stateAddressbook.$inject=["$stateParams","AddressBook"],stateNewCard.$inject=["$stateParams","stateAddressbook","Card"],stateCard.$inject=["$stateParams","stateAddressbook"],runBlock.$inject=["$rootScope"]}(),function(){"use strict";function AddressBookController($scope,$state,$timeout,$mdDialog,focus,Card,AddressBook,Dialog,Settings,stateAddressbooks,stateAddressbook){function selectCard(card){$state.go("app.addressbook.card.view",{addressbookId:stateAddressbook.id,cardId:card.id})}function newComponent(ev){function ComponentDialogController(scope,$mdDialog,$state,addressbookId){scope.create=function(type){$mdDialog.hide(),$state.go("app.addressbook.new",{addressbookId:addressbookId,contactType:type})}}$mdDialog.show({parent:angular.element(document.body),targetEvent:ev,clickOutsideToClose:!0,escapeToClose:!0,template:['<md-dialog aria-label="'+l("Create component")+'">'," <md-dialog-content>",' <div layout="column">'," <md-button ng-click=\"create('card')\">"," "+l("Contact")," </md-button>"," <md-button ng-click=\"create('list')\">"," "+l("List")," </md-button>"," </div>"," </md-dialog-content>","</md-dialog>"].join(""),locals:{addressbookId:vm.selectedFolder.id},controller:ComponentDialogController}),ComponentDialogController.$inject=["scope","$mdDialog","$state","addressbookId"]}function notSelectedComponent(currentCard,type){return currentCard&&currentCard.c_component==type&&!currentCard.selected}function unselectCards(){_.each(vm.selectedFolder.cards,function(card){card.selected=!1})}function confirmDeleteSelectedCards(){Dialog.confirm(l("Warning"),l("Are you sure you want to delete the selected contacts?")).then(function(){var selectedCards=_.filter(vm.selectedFolder.cards,function(card){return card.selected});vm.selectedFolder.$deleteCards(selectedCards),delete vm.selectedFolder.selectedCard},function(data,status){})}function saveSelectedCards(){var selectedCards=_.filter(vm.selectedFolder.cards,function(card){return card.selected}),selectedUIDs=_.pluck(selectedCards,"id");window.location.href=ApplicationBaseURL+"/"+vm.selectedFolder.id+"/export?uid="+selectedUIDs.join("&uid=")}function copySelectedCards(folder){var selectedCards=_.filter(vm.selectedFolder.cards,function(card){return card.selected});vm.selectedFolder.$copyCards(selectedCards,folder).then(function(){},function(error){Dialog.alert(l("Error"),error)})}function selectAll(){_.each(vm.selectedFolder.cards,function(card){card.selected=!0})}function sort(field){vm.selectedFolder.$filter("",{sort:field})}function sortedBy(field){return vm.selectedFolder.$query.sort==field}function cancelSearch(){vm.mode.search=!1,vm.selectedFolder.$filter("")}var vm=this;AddressBook.selectedFolder=stateAddressbook,vm.selectedFolder=stateAddressbook,vm.selecLine truncated
//# sourceMappingURL=Contacts.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Contacts.js","sources":["Contacts/Contacts.app.js","Contacts/AddressBookController.js","Contacts/AddressBooksController.js","Contacts/CardController.js","Contacts/sgAddress.directive.js"],"names":["configure","$stateProvider","$urlRouterProvider","state","url","abstract","views","addressbooks","templateUrl","controller","controllerAs","resolve","stateAddressbooks","addressbook","stateAddressbook","card","stateCard","stateNewCard","template","card@app.addressbook","otherwise","AddressBook","$findAll","window","contactFolders","$stateParams","$find","addressbookId","$futureAddressBookData","Card","tag","contactType","pid","c_component","selectedCard","cardId","$getCard","runBlock","$rootScope","$on","event","current","previous","rejection","console","error","angular","module","config","run","$inject","AddressBookController","$scope","$state","$timeout","$mdDialog","focus","Dialog","Settings","selectCard","go","id","newComponent","ev","ComponentDialogController","scope","create","type","hide","show","parent","element","document","body","targetEvent","clickOutsideToClose","escapeToClose","l","join","locals","vm","selectedFolder","notSelectedComponent","currentCard","selected","unselectCards","_","each","cards","confirmDeleteSelectedCards","confirm","then","selectedCards","filter","$deleteCards","data","status","saveSelectedCards","selectedUIDs","pluck","location","href","ApplicationBaseURL","copySelectedCards","folder","$copyCards","alert","selectAll","sort","field","$filter","sortedBy","$query","cancelSearch","mode","search","this","AddressBooksController","User","select","editMode","newAddressbook","prompt","name","isEditable","isRemote","owner","UserLogin","$add","edit","originalAddressbook","extend","$omit","revertEditing","save","length","$rename","confirmDelete","service","isSubscription","$delete","importCards","exportCards","showLinks","LinksDialogController","close","share","$acl","$users","usersWithACL","users","subscribeToFolder","addressbookData","debug","$subscribe","activeUser","CardController","addOrgUnit","i","$addOrgUnit","addEmail","$addEmail","addPhone","$addPhone","addUrl","$addUrl","addAddress","$addAddress","addMember","$addMember","userFilter","excludedCards","dry","excludeLists","$cards","form","$valid","$save","indexOf","$reload","copy","err","log","reset","$reset","cancel","isNew","$fullname","ok","reject","o","viewRawSource","$event","$$resource","post","currentFolder","CardRawSourceDialogController","allEmailTypes","$EMAIL_TYPES","allTelTypes","$TEL_TYPES","allUrlTypes","$URL_TYPES","allAddressTypes","$ADDRESS_TYPES","categories","userFilterResults","sgAddress","restrict","addressLines","lines","locality_region","street","push","street2","locality","region","country","postalcode","directive"],"mappings":"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 truncated
@@ -0,0 +1,2 @@
!function(){"use strict";function AddressBook(futureAddressBookData){if("function"!=typeof futureAddressBookData.then)if(this.init(futureAddressBookData),this.name&&!this.id){var newAddressBookData=AddressBook.$$resource.create("createFolder",this.name);this.$unwrap(newAddressBookData)}else this.id&&(this.$acl=new AddressBook.$$Acl("Contacts/"+this.id));else this.$unwrap(futureAddressBookData)}AddressBook.$factory=["$q","$timeout","$log","sgSettings","Resource","Card","Acl","Preferences",function($q,$timeout,$log,Settings,Resource,Card,Acl,Preferences){return angular.extend(AddressBook,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL")+"Contacts",Settings.activeUser()),$Card:Card,$$Acl:Acl,$Preferences:Preferences,activeUser:Settings.activeUser(),selectedFolder:null,$refreshTimeout:null}),AddressBook}];try{angular.module("SOGo.ContactsUI")}catch(e){angular.module("SOGo.ContactsUI",["SOGo.Common"])}angular.module("SOGo.ContactsUI").factory("AddressBook",AddressBook.$factory),AddressBook.$filterAll=function(search,options,excludedCards){var params={search:search};if(!search)return AddressBook.$cards=[],AddressBook.$q.when(AddressBook.$cards);if(angular.isUndefined(AddressBook.$cards))AddressBook.$cards=[];else if(AddressBook.$query==search)return AddressBook.$q.when(AddressBook.$cards);return AddressBook.$query=search,angular.extend(params,options),AddressBook.$$resource.fetch(null,"allContactSearch",params).then(function(response){var results,card,index,compareIds=function(data){return this.id==data.id};for(results=excludedCards?_.filter(response.contacts,function(data){return _.isUndefined(_.find(excludedCards,compareIds,data))}):response.contacts,index=AddressBook.$cards.length-1;index>=0;index--)card=AddressBook.$cards[index],_.isUndefined(_.find(results,compareIds,card))&&AddressBook.$cards.splice(index,1);return _.each(results,function(data,index){if(_.isUndefined(_.find(AddressBook.$cards,compareIds,data))){var card=new AddressBook.$Card(data,search);AddressBook.$cards.splice(index,0,card)}}),AddressBook.$cards})},AddressBook.$add=function(addressbook){var list,sibling,i;list=addressbook.isSubscription?this.$subscriptions:this.$addressbooks,sibling=_.find(list,function(o){return"personal"==addressbook.id||"personal"!=o.id&&1===o.name.localeCompare(addressbook.name)}),i=sibling?_.indexOf(_.pluck(list,"id"),sibling.id):1,list.splice(i,0,addressbook)},AddressBook.$findAll=function(data){var _this=this;return data&&(this.$addressbooks=[],this.$subscriptions=[],this.$remotes=[],angular.forEach(data,function(o,i){var addressbook=new AddressBook(o);addressbook.isRemote?_this.$remotes.push(addressbook):addressbook.isSubscription?_this.$subscriptions.push(addressbook):_this.$addressbooks.push(addressbook)})),this.$addressbooks},AddressBook.$find=function(addressbookId){var futureAddressBookData=AddressBook.$$resource.fetch(addressbookId,"view");return new AddressBook(futureAddressBookData)},AddressBook.$subscribe=function(uid,path){var _this=this;return AddressBook.$$resource.userResource(uid).fetch(path,"subscribe").then(function(addressbookData){var addressbook=new AddressBook(addressbookData);return _.isUndefined(_.find(_this.$subscriptions,function(o){return o.id==addressbookData.id}))&&AddressBook.$add(addressbook),addressbook})},AddressBook.prototype.init=function(data){this.$cards=[],this.cards=[],angular.extend(this,data),this.isOwned=AddressBook.activeUser.isSuperUser||this.owner==AddressBook.activeUser.login,this.isSubscription=!this.isRemote&&this.owner!=AddressBook.activeUser.login,this.$query={search:"name_or_address",value:"",sort:"c_cn",asc:"true"}},AddressBook.prototype.$id=function(){return this.id?AddressBook.$q.when(this.id):this.$futureAddressBookData.then(function(addressbook){return addressbook.id})},AddressBook.prototype.$selectedCount=function(){var count;return count=0,this.cards&&(count=_.filter(this.cards,function(card){return card.selected}).length),count},AddressBook.prototype.$startRefreshTimeout=function(){var _this=this;AddressBook.$refreshTimeout&&AddressBook.$timeout.cancel(AddressBook.$refreshTimeout),AddressBook.$Preferences.ready().then(function(){var refreshViewCheck=AddressBook.$Preferences.defaults.SOGoRefreshViewCheck;if(refreshViewCheck&&"manually"!=refreshViewCheck){var f=angular.bind(_this,AddressBook.prototype.$reload);AddressBook.$refreshTimeout=AddressBook.$timeout(f,1e3*refreshViewCheck.timeInterval())}})},AddressBook.prototype.$reload=function(){var _this=this;return this.$startRefreshTimeout(),AddressBook.$$resource.fetch(this.id,"view").then(function(response){var index,card,results=response.cards,cards=_this.cards,compareIds=function(data){return this.id==data.id};for(index=cards.length-1;index>=0;index--)card=cards[index],_.isUndefined(_.find(results,compareIds,card))&&cards.splice(index,1);return _.each(results,function(data,index){if(_.isUndefined(_.find(cards,compareIds,data))){var card=new AddressBook.$Card(data);Line truncated
//# sourceMappingURL=Contacts.services.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Contacts.services.js","sources":["Contacts/AddressBook.service.js","Contacts/Card.service.js"],"names":["AddressBook","futureAddressBookData","then","this","init","name","id","newAddressBookData","$$resource","create","$unwrap","$acl","$$Acl","$factory","$q","$timeout","$log","Settings","Resource","Card","Acl","Preferences","angular","extend","activeUser","$Card","$Preferences","selectedFolder","$refreshTimeout","module","e","factory","$filterAll","search","options","excludedCards","params","$cards","when","isUndefined","$query","fetch","response","results","card","index","compareIds","data","_","filter","contacts","find","length","splice","each","$add","addressbook","list","sibling","i","isSubscription","$subscriptions","$addressbooks","o","localeCompare","indexOf","pluck","$findAll","_this","$remotes","forEach","isRemote","push","$find","addressbookId","$subscribe","uid","path","userResource","addressbookData","prototype","cards","isOwned","isSuperUser","owner","login","value","sort","asc","$id","$futureAddressBookData","$selectedCount","count","selected","$startRefreshTimeout","cancel","ready","refreshViewCheck","defaults","SOGoRefreshViewCheck","f","bind","$reload","timeInterval","$filter","dry","oldIndex","removedCards","findIndex","$rename","$save","$delete","promise","d","defer","remove","resolve","status","reject","$deleteCards","uids","map","post","difference","$copyCards","folder","save","$omit","$getCard","cardId","isError","isObject","key","futureCardData","partial","pid","newCardData","newguid","isNew","$TEL_TYPES","$EMAIL_TYPES","$URL_TYPES","$ADDRESS_TYPES","Gravatar","$gravatar","SOGoContactsCategories","$categories","join","$unwrapCollection","filterCategories","query","re","RegExp","category","collection","$futureCardData","refs","$$fullname","$fullname","$$email","$preferredEmail","$$image","image","empty","action","c_component","$shadowData","attribute","names","fn","c_cn","c_givenname","nickname","c_sn","c_org","emails","$description","description","title","role","orgUnits","unit","org","email","test","type","$shortFormat","fullname","$birthday","Date","birthday","$isCard","$isList","$addOrgUnit","orgUnit","$addCategory","categories","$addEmail","$addPhone","phones","$addUrl","url","urls","$addAddress","postoffice","street","street2","locality","region","country","postalcode","addresses","$addMember","$reset","reference","deep","copy","toString","desc"],"mappings":"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 truncated
@@ -454,6 +454,17 @@
});
};
/**
* @function $copyCards
* @memberof AddressBook.prototype
* @desc Copy multiple cards from addressbook to an other one.
* @return a promise of the HTTP operation
*/
AddressBook.prototype.$copyCards = function(cards, folder) {
var uids = _.map(cards, function(card) { return card.id; });
return AddressBook.$$resource.post(this.id, 'copy', {uids: uids, folder: folder});
};
/**
* @function $save
* @memberof AddressBook.prototype
@@ -19,6 +19,7 @@
vm.unselectCards = unselectCards;
vm.confirmDeleteSelectedCards = confirmDeleteSelectedCards;
vm.saveSelectedCards = saveSelectedCards;
vm.copySelectedCards = copySelectedCards;
vm.selectAll = selectAll;
vm.sort = sort;
vm.sortedBy = sortedBy;
@@ -94,6 +95,15 @@
window.location.href = ApplicationBaseURL + '/' + vm.selectedFolder.id + '/export?uid=' + selectedUIDs.join('&uid=');
}
function copySelectedCards(folder) {
var selectedCards = _.filter(vm.selectedFolder.cards, function(card) { return card.selected; });
vm.selectedFolder.$copyCards(selectedCards, folder).then(function() {
// TODO: refresh target addressbook?
}, function(error) {
Dialog.alert(l('Error'), error);
});
}
function selectAll() {
_.each(vm.selectedFolder.cards, function(card) {
card.selected = true;
@@ -99,7 +99,8 @@
}
function confirmDelete(card) {
Dialog.confirm(l('Warning'),
l('Are you sure you want to delete the card of %{0}?', card.$fullname()))
l('Are you sure you want to delete the card of %{0}?', card.$fullname()),
{ok: l('Yes'), cancel: l('No')})
.then(function() {
// User confirmed the deletion
card.$delete()
+2
View File
@@ -0,0 +1,2 @@
!function(){"use strict";function configure($stateProvider,$urlRouterProvider){$stateProvider.state("mail",{url:"/Mail",views:{mailboxes:{templateUrl:"UIxMailMainFrame",controller:"MailboxesController",controllerAs:"app"}},resolve:{stateAccounts:stateAccounts}}).state("mail.account",{url:"/:accountId","abstract":!0,views:{mailbox:{template:"<ui-view/>"}},resolve:{stateAccount:stateAccount}}).state("mail.account.mailbox",{url:"/:mailboxId",views:{"mailbox@mail":{templateUrl:"UIxMailFolderTemplate",controller:"MailboxController",controllerAs:"mailbox"}},resolve:{stateMailbox:stateMailbox,stateMessages:stateMessages}}).state("mail.account.mailbox.message",{url:"/:messageId",views:{message:{templateUrl:"UIxMailViewTemplate",controller:"MessageController",controllerAs:"viewer"}},resolve:{stateMessage:stateMessage}}),$urlRouterProvider.otherwise("/Mail")}function stateAccounts($q,Account){var accounts=Account.$findAll(mailAccounts),promises=[];return angular.forEach(accounts,function(account,i){var mailboxes=account.$getMailboxes();promises.push(mailboxes.then(function(objects){return account}))}),$q.all(promises)}function stateAccount($stateParams,stateAccounts){return _.find(stateAccounts,function(account){return account.id==$stateParams.accountId})}function stateMailbox($stateParams,stateAccount,decodeUriFilter){var _find,mailboxId=decodeUriFilter($stateParams.mailboxId);return(_find=function(mailboxes){var mailbox=_.find(mailboxes,function(o){return o.path==mailboxId});return mailbox||angular.forEach(mailboxes,function(o){!mailbox&&o.children&&o.children.length>0&&(mailbox=_find(o.children))}),mailbox})(stateAccount.$mailboxes)}function stateMessages(stateMailbox){return stateMailbox.$filter()}function stateMessage(encodeUriFilter,$stateParams,$state,stateMailbox,stateMessages){var message=_.find(stateMailbox.$messages,function(messageObject){return messageObject.uid==$stateParams.messageId});return message?(stateMailbox.selectedMessage=$stateParams.messageId,message.$reload()):void $state.go("mail.account.mailbox",{accountId:stateMailbox.$account.id,mailboxId:encodeUriFilter(stateMailbox.path)})}function runBlock($rootScope){$rootScope.$on("$routeChangeError",function(event,current,previous,rejection){console.error(event,current,previous,rejection)})}angular.module("SOGo.MailerUI",["ngSanitize","ui.router","ck","angularFileUpload","SOGo.Common","SOGo.ContactsUI","ngAnimate","SOGo.PreferencesUI"]).config(configure).run(runBlock),configure.$inject=["$stateProvider","$urlRouterProvider"],stateAccounts.$inject=["$q","Account"],stateAccount.$inject=["$stateParams","stateAccounts"],stateMailbox.$inject=["$stateParams","stateAccount","decodeUriFilter"],stateMessages.$inject=["stateMailbox"],stateMessage.$inject=["encodeUriFilter","$stateParams","$state","stateMailbox","stateMessages"],runBlock.$inject=["$rootScope"]}(),function(){"use strict";function MailboxController($state,$timeout,$mdDialog,stateAccounts,stateAccount,stateMailbox,encodeUriFilter,focus,Dialog,Account,Mailbox){function selectMessage(message){$state.go("mail.account.mailbox.message",{accountId:stateAccount.id,mailboxId:encodeUriFilter(stateMailbox.path),messageId:message.uid})}function unselectMessages(){_.each(vm.selectedFolder.$messages,function(message){message.selected=!1})}function confirmDeleteSelectedMessages(){Dialog.confirm(l("Warning"),l("Are you sure you want to delete the selected messages?")).then(function(){var selectedMessages=_.filter(vm.selectedFolder.$messages,function(message){return message.selected}),selectedUIDs=_.pluck(selectedMessages,"uid");vm.selectedFolder.$deleteMessages(selectedUIDs).then(function(){var unseenCount=_.filter(selectedMessages,function(message){return!message.isread});vm.selectedFolder.$messages=_.difference(vm.selectedFolder.$messages,selectedMessages),vm.selectedFolder.unseenCount=-unseenCount},function(error){Dialog.alert(l("Error"),error)})})}function copySelectedMessages(folder){var selectedMessages=_.filter(vm.selectedFolder.$messages,function(message){return message.selected}),selectedUIDs=_.pluck(selectedMessages,"uid");vm.selectedFolder.$copyMessages(selectedUIDs,"/"+folder).then(function(){},function(error){Dialog.alert(l("Error"),error)})}function saveSelectedMessages(){var selectedMessages=_.filter(vm.selectedFolder.$messages,function(message){return message.selected}),selectedUIDs=_.pluck(selectedMessages,"uid");window.location.href=ApplicationBaseURL+"/"+vm.selectedFolder.id+"/saveMessages?uid="+selectedUIDs.join(",")}function selectAll(){_.each(vm.selectedFolder.$messages,function(message){message.selected=!0})}function markSelectedMessagesAsFlagged(){var selectedMessages=_.filter(vm.selectedFolder.$messages,function(message){return message.selected}),selectedUIDs=_.pluck(selectedMessages,"uid");vm.selectedFolder.$flagMessages(selectedUIDs,"\\Flagged","add").then(function(d){_.forEach(selectedMessages,function(message){message.isflagged=!0})})}function markSelectedMessagesAsUnread(){var seLine truncated
//# sourceMappingURL=Mailer.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Mailer.js","sources":["Mailer/Mailer.app.js","Mailer/MailboxController.js","Mailer/MailboxesController.js","Mailer/MessageController.js","Mailer/MessageEditorController.js","Mailer/sgIMIP.directive.js"],"names":["configure","$stateProvider","$urlRouterProvider","state","url","views","mailboxes","templateUrl","controller","controllerAs","resolve","stateAccounts","abstract","mailbox","template","stateAccount","mailbox@mail","stateMailbox","stateMessages","message","stateMessage","otherwise","$q","Account","accounts","$findAll","mailAccounts","promises","angular","forEach","account","i","$getMailboxes","push","then","objects","all","$stateParams","_","find","id","accountId","decodeUriFilter","_find","mailboxId","o","path","children","length","$mailboxes","$filter","encodeUriFilter","$state","$messages","messageObject","uid","messageId","selectedMessage","$reload","go","$account","runBlock","$rootScope","$on","event","current","previous","rejection","console","error","module","config","run","$inject","MailboxController","$timeout","$mdDialog","focus","Dialog","Mailbox","selectMessage","unselectMessages","each","vm","selectedFolder","selected","confirmDeleteSelectedMessages","confirm","l","selectedMessages","filter","selectedUIDs","pluck","$deleteMessages","unseenCount","isread","difference","alert","copySelectedMessages","folder","$copyMessages","saveSelectedMessages","window","location","href","ApplicationBaseURL","join","selectAll","markSelectedMessagesAsFlagged","$flagMessages","d","isflagged","markSelectedMessagesAsUnread","sort","field","sortedBy","$query","cancelSearch","mode","search","newMessage","$event","$newMessage","show","parent","element","document","body","targetEvent","clickOutsideToClose","escapeToClose","locals","stateRecipients","this","service","MailboxesController","Settings","User","Preferences","newFolder","parentFolder","prompt","name","$newMailbox","data","status","delegate","MailboxDelegationController","$scope","userFilter","delegates","closeModal","hide","removeUser","user","$removeDelegate","addUser","$addDelegate","userToAdd","searchText","users","editFolder","editMode","revertEditing","$reset","selectFolder","saveFolder","$rename","compactFolder","$compact","emptyTrashFolder","$emptyTrash","exportMails","confirmDelete","$delete","markFolderRead","$markAsRead","share","$acl","$users","usersWithACL","metadataForFolder","type","icon","setFolderAs","$setFolderAs","reload","refreshUnseenCount","unseenCountFolders","includes","$$flattenMailboxes","isDefined","$$resource","post","ready","refreshViewCheck","defaults","SOGoRefreshViewCheck","timeInterval","MessageController","Message","doDelete","index","findIndex","splice","showMailEditor","recipients","reply","$reply","replyAll","$replyAll","forward","$forward","edit","$editableContent","recipient","viewRawSource","MessageRawSourceDialogController","scope","close","tags","$watchCollection","oldTags","newTags","tag","removeTag","MessageEditorController","FileUploader","AddressBook","cancel","autosave","send","$send","contactFilter","deferred","defer","$filterAll","results","invoke","promise","autosaveDrafts","$save","SOGoMailAutoSave","autocomplete","to","cc","bcc","hideCc","hideBcc","identities","flatten","uploader","$absolutePath","asDraft","autoUpload","alias","onProgressItem","item","progress","debug","onSuccessItem","response","headers","$setUID","JSON","stringify","undefined","onCancelItem","$deleteAttachment","file","removeFromQueue","onErrorItem","actionName","msgObject","editable","union","localeCode","LocaleCode","sgImip","link","iElement","attrs","ctrl","pathToAttachment","sgImipPath","restrict","sgImipController","delegateInvitation","delegatedTo","iCalendarAction","action","receiveUpdates","c_email","viewer","$imipAction","directive"],"mappings":"CAGA,WACE,YAUA,SAASA,WAAUC,eAAgBC,oBACjCD,eACGE,MAAM,QACLC,IAAK,QACLC,OACEC,WACEC,YAAa,mBACbC,WAAY,sBACZC,aAAc,QAGlBC,SACEC,cAAeA,iBAGlBR,MAAM,gBACLC,IAAK,cACLQ,YAAU,EACVP,OACEQ,SACEC,SAAU,eAGdJ,SACEK,aAAcA,gBAGjBZ,MAAM,wBACLC,IAAK,cACLC,OACEW,gBACET,YAAa,wBACbC,WAAY,oBACZC,aAAc,YAGlBC,SACEO,aAAcA,aACdC,cAAeA,iBAgBlBf,MAAM,gCACLC,IAAK,cACLC,OACEc,SACEZ,YAAa,sBACbC,WAAY,oBACZC,aAAc,WAGlBC,SACEU,aAAcA,gBA4BpBlB,mBAAmBmB,UAAU,SAc/B,QAASV,eAAcW,GAAIC,SACzB,GAAIC,UAAWD,QAAQE,SAASC,cAC5BC,WAQJ,OANAC,SAAQC,QAAQL,SAAU,SAASM,QAASC,GAC1C,GAAIzB,WAAYwB,QAAQE,eACxBL,UAASM,KAAK3B,UAAU4B,KAAK,SAASC,SACpC,MAAOL,cAGJR,GAAGc,IAAIT,UAOhB,QAASZ,cAAasB,aAAc1B,eAClC,MAAO2B,GAAEC,KAAK5B,cAAe,SAASmB,SACpC,MAAOA,SAAQU,IAAMH,aAAaI,YAQtC,QAASxB,cAAaoB,aAActB,aAAc2B,iBAChD,GACIC,OADAC,UAAYF,gBAAgBL,aAAaO,UAgB7C,QAbAD,MAAQ,SAASrC,WACf,GAAIO,SAAUyB,EAAEC,KAAKjC,UAAW,SAASuC,GACvC,MAAOA,GAAEC,MAAQF,WASnB,OAPK/B,UACHe,QAAQC,QAAQvB,UAAW,SAASuC,IAC7BhC,SAAWgC,EAAEE,UAAYF,EAAEE,SAASC,OAAS,IAChDnC,QAAU8B,MAAME,EAAEE,aAIjBlC,UAEIE,aAAakC,YAO5B,QAAS/B,eAAcD,cACrB,MAAOA,cAAaiC,UAetB,QAAS9B,cAAa+B,gBAAiBd,aAAce,OAAQnC,aAAcC,eACzE,GAAIC,SAAUmB,EAAEC,KAAKtB,aAAaoC,UAAW,SAASC,eACpD,MAAOA,eAAcC,KAAOlB,aAALine truncated
@@ -0,0 +1,2 @@
!function(){"use strict";function Account(futureAccountData){"function"!=typeof futureAccountData.then&&(angular.extend(this,futureAccountData),_.each(this.identities,function(identity){identity.fullName?identity.full=identity.fullName+" <"+identity.email+">":identity.full="<"+identity.email+">"}),Account.$log.debug("Account: "+JSON.stringify(futureAccountData,void 0,2)))}Account.$factory=["$q","$timeout","$log","sgSettings","Resource","Mailbox","Message",function($q,$timeout,$log,Settings,Resource,Mailbox,Message){return angular.extend(Account,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.baseURL(),Settings.activeUser()),$Mailbox:Mailbox,$Message:Message}),Account}];try{angular.module("SOGo.MailerUI")}catch(e){angular.module("SOGo.MailerUI",["SOGo.Common"])}angular.module("SOGo.MailerUI").factory("Account",Account.$factory),Account.$findAll=function(data){var collection=[];return data&&angular.forEach(data,function(o,i){o.id=i,collection[i]=new Account(o)}),collection},Account.prototype.$getMailboxes=function(options){var _this=this,deferred=Account.$q.defer();return!this.$mailboxes||options&&options.reload?Account.$Mailbox.$find(this).then(function(data){_this.$mailboxes=data,_this.$flattenMailboxes({reload:!0}),deferred.resolve(_this.$mailboxes)}):deferred.resolve(this.$mailboxes),deferred.promise},Account.prototype.$flattenMailboxes=function(options){var _this=this,allMailboxes=[],_visit=function(mailboxes){_.each(mailboxes,function(o){allMailboxes.push(o),o.children&&o.children.length>0&&_visit(o.children)})};return!this.$$flattenMailboxes||options&&options.reload?(_visit(this.$mailboxes),_this.$$flattenMailboxes=allMailboxes):allMailboxes=this.$$flattenMailboxes,allMailboxes},Account.prototype.$getMailboxByType=function(type){var mailbox,_find=function(mailboxes){var mailbox=_.find(mailboxes,function(o){return o.type==type});return mailbox||angular.forEach(mailboxes,function(o){!mailbox&&o.children&&o.children.length>0&&(mailbox=_find(o.children))}),mailbox};mailbox=_find(this.$mailboxes),console.debug(mailbox),console.debug(this.specialMailboxes)},Account.prototype.$getMailboxByPath=function(path){var mailbox=null,_find=function(mailboxes){var mailbox=_.find(mailboxes,function(o){return o.path==path});return mailbox||angular.forEach(mailboxes,function(o){!mailbox&&o.children&&o.children.length>0&&(mailbox=_find(o.children))}),mailbox};return mailbox=_find(this.$mailboxes)},Account.prototype.$newMailbox=function(path,name){var _this=this,deferred=Account.$q.defer();return Account.$$resource.post(path,"createFolder",{name:name}).then(function(){_this.$getMailboxes({reload:!0}),deferred.resolve()},function(response){deferred.reject(response.error)}),deferred.promise},Account.prototype.$newMessage=function(){var _this=this;return Account.$$resource.fetch(this.id.toString(),"compose").then(function(data){Account.$log.debug("New message (compose): "+JSON.stringify(data,void 0,2));var message=new Account.$Message(data.accountId,_this.$getMailboxByPath(data.mailboxPath),data);return message}).then(function(message){return Account.$$resource.fetch(message.$absolutePath({asDraft:!0}),"edit").then(function(data){return Account.$log.debug("New message (edit): "+JSON.stringify(data,void 0,2)),angular.extend(message.editable,data),message})})},Account.prototype.$addDelegate=function(user){var _this=this,deferred=Account.$q.defer(),param={uid:user.uid};return!user.uid||_.indexOf(_.pluck(this.delegates,"uid"),user.uid)>-1?deferred.resolve():Account.$$resource.fetch(this.id.toString(),"addDelegate",param).then(function(){_this.delegates.push(user),deferred.resolve(_this.users)},function(data,status){deferred.reject(l("An error occured please try again."))}),deferred.promise},Account.prototype.$removeDelegate=function(uid){var _this=this,param={uid:uid};return Account.$$resource.fetch(this.id.toString(),"removeDelegate",param).then(function(){var i=_.indexOf(_.pluck(_this.delegates,"uid"),uid);i>=0&&_this.delegates.splice(i,1)})}}(),function(){"use strict";function Mailbox(account,futureMailboxData){if(this.$account=account,"function"!=typeof futureMailboxData.then){if(this.init(futureMailboxData),this.name&&!this.path){var newMailboxData=Mailbox.$$resource.create("createFolder",this.name);this.$unwrap(newMailboxData)}}else this.$unwrap(futureMailboxData)}Mailbox.$factory=["$q","$timeout","$log","sgSettings","Resource","Message","Acl","Preferences","sgMailbox_PRELOAD",function($q,$timeout,$log,Settings,Resource,Message,Acl,Preferences,PRELOAD){return angular.extend(Mailbox,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL")+"Mail",Settings.activeUser()),$Message:Message,$$Acl:Acl,$Preferences:Preferences,$query:{sort:"date",asc:0},selectedFolder:null,$refreshTimeout:null,PRELOAD:PRELOAD}),Preferences.ready().then(function(){Preferences.settings.Mail.SortingState&&(Mailbox.$query.sort=Preferences.settings.Mail.SortingState[0],Mailbox.$query.asc=parseInt(PreLine truncated
//# sourceMappingURL=Mailer.services.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Mailer.services.js","sources":["Mailer/Account.service.js","Mailer/Mailbox.service.js","Mailer/Message.service.js"],"names":["Account","futureAccountData","then","angular","extend","this","_","each","identities","identity","fullName","full","email","$log","debug","JSON","stringify","undefined","$factory","$q","$timeout","Settings","Resource","Mailbox","Message","$$resource","baseURL","activeUser","$Mailbox","$Message","module","e","factory","$findAll","data","collection","forEach","o","i","id","prototype","$getMailboxes","options","_this","deferred","defer","$mailboxes","reload","$find","$flattenMailboxes","resolve","promise","allMailboxes","_visit","mailboxes","push","children","length","$$flattenMailboxes","$getMailboxByType","type","mailbox","_find","find","console","specialMailboxes","$getMailboxByPath","path","$newMailbox","name","post","response","reject","error","$newMessage","fetch","toString","message","accountId","mailboxPath","$absolutePath","asDraft","editable","$addDelegate","user","param","uid","indexOf","pluck","delegates","users","status","l","$removeDelegate","splice","account","futureMailboxData","$account","init","newMailboxData","create","$unwrap","Acl","Preferences","PRELOAD","$$Acl","$Preferences","$query","sort","asc","selectedFolder","$refreshTimeout","ready","settings","Mail","SortingState","parseInt","constant","LOOKAHEAD","SIZE","$unwrapCollection","createMailboxes","level","index","map","split","component","asCSSIdentifier","join","$isLoading","$messages","uidsMap","$id","$acl","$isEditable","isEditable","isUndefined","$shadowData","$omit","$selectedCount","count","filter","selected","$filter","sortingAttributes","filters","isDefined","unseenCount","cancel","searchInput","secondFilter","match","searchBy","copy","refreshViewCheck","defaults","SOGoRefreshViewCheck","f","bind","timeInterval","$loadMessage","messageId","endIndex","uids","futureHeadersData","startIndex","max","loaded","subject","Math","min","loading","$unwrapHeaders","$rename","findParent","parent","parentMailbox","$save","sibling","localeCompare","$compact","$setFolderAs","$emptyTrash","$markAsRead","$flagMessages","flags","operation","msgUIDs","$delete","remove","$deleteMessages","$copyMessages","folder","$moveMessages","$reset","value","key","save","$futureMailboxData","headers","invoke","threaded","reduce","msgs","msg","object","isError","j","messageHeaders","futureMessageData","$mailbox","$hasUnsafeContent","$loadUnsafeContent","to","cc","bcc","$formatFullAddresses","$sce","Gravatar","$gravatar","SOGoMailLabelsColors","$tags","filterTags","query","re","RegExp","keys","tag","search","draftId","$setUID","oldUID","$shortAddress","address","loadUnsafeContent","$content","parts","part","msgclass","content","alternatePart","preferredPart","contentType","isArray","mixedPart","safeContent","html","unsafeContent","document","createElement","innerHTML","suffix","element","elements","querySelectorAll","attr","removeAttr","trustAs","participants","participant","image","compile","$editableContent","text","addTag","$addOrRemoveTag","removeTag","$imipAction","action","$reload","$sendMDN","shouldAskReceipt","$deleteAttachment","filename","attachmentAttrs","attachment","toggleFlag","isflagged","$reply","$newDraft","$replyAll","$forward","$send","$futureMessageData","isread"],"mappings":"CAEA,WACE,YAOA,SAASA,SAAQC,mBAEuB,kBAA3BA,mBAAkBC,OAC3BC,QAAQC,OAAOC,KAAMJ,mBACrBK,EAAEC,KAAKF,KAAKG,WAAY,SAASC,UAC3BA,SAASC,SACXD,SAASE,KAAOF,SAASC,SAAW,KAAOD,SAASG,MAAQ,IAE5DH,SAASE,KAAO,IAAMF,SAASG,MAAQ,MAE3CZ,QAAQa,KAAKC,MAAM,YAAcC,KAAKC,UAAUf,kBAAmBgB,OAAW,KAalFjB,QAAQkB,UAAY,KAAM,WAAY,OAAQ,aAAc,WAAY,UAAW,UAAW,SAASC,GAAIC,SAAUP,KAAMQ,SAAUC,SAAUC,QAASC,SAUtJ,MATArB,SAAQC,OAAOJ,SACbmB,GAAIA,GACJC,SAAUA,SACVP,KAAMA,KACNY,WAAY,GAAIH,UAASD,SAASK,UAAWL,SAASM,cACtDC,SAAUL,QACVM,SAAUL,UAGLxB,SAOT,KACEG,QAAQ2B,OAAO,iBAEjB,MAAMC,GACJ5B,QAAQ2B,OAAO,iBAAkB,gBAEnC3B,QAAQ2B,OAAO,iBACZE,QAAQ,UAAWhC,QAAQkB,UAQ9BlB,QAAQiC,SAAW,SAASC,MAC1B,GAAIC,cAQJ,OAPID,OAEF/B,QAAQiC,QAAQF,KAAM,SAASG,EAAGC,GAChCD,EAAEE,GAAKD,EACPH,WAAWG,GAAK,GAAItC,SAAQqC,KAGzBF,YAUTnC,QAAQwC,UAAUC,cAAgB,SAASC,SACzC,GAAIC,OAAQtC,KACRuC,SAAW5C,QAAQmB,GAAG0B,OAa1B,QAXIxC,KAAKyC,YAAgBJ,SAAWA,QAAQK,OAI1C/C,QAAQ4B,SAASoB,MAAM3C,MAAMH,KAAK,SAASgC,MACzCS,MAAMG,WAAaZ,KACnBS,MAAMM,mBAAmBF,QAAQ,IACjCH,SAASM,QAAQP,MAAMG,cANzBF,SAASM,QAAQ7C,KAAKyC,YAUjBF,SAASO,SAUlBnD,QAAQwC,UAAUS,kBAAoB,SAASP,SAC7C,GAAIC,OAAQtC,KACR+C,gBACAC,OAAS,SAASC,WAChBhD,EAAEC,KAAK+C,UAAW,SAASjB,GACzBe,aAAaG,KAAKlB,GACdA,EAAEmB,UAAYnB,EAAEmB,SAASC,OAAS,GACpCJ,OAAOhB,EAAEmB,YAanB,QARInD,KAAKqD,oBAAwBhB,SAAWA,QAAQK,QAIlDM,OAAOhD,KAAKyC,YACZH,MAAMe,mBAAqBN,cAJ3BA,aAAe/C,KAAKqD,mBAOfN,cAGTpD,QAAQwC,UAAUmB,kBAAoB,SAASC,MAC7C,GAAIC,SAEAC,MAAQ,SAASR,WACf,GAAIO,SAAUvD,EAAEyD,KAAKT,UAAW,SAASjB,GACvC,MAAOA,GAAEuB,MAAQA,MASnB,OAPKC,UACH1D,QAAQiC,QAAQkB,UAAW,SAASjB,IAC7BwB,SAAWxB,EAAEmB,UAAYnB,EAAEmB,SAASC,OAAS,IAChDI,QAAUC,MAAMzB,EAAEmB,aAIjBK,QAEbA,SAAUC,MAAMzD,KAAKyC,YAErBkB,QAAQlD,MAAM+C,SACdG,QAAQlD,MAAMT,KAAK4D,mLine truncated
@@ -210,13 +210,13 @@
// Query account for draft folder and draft UID
return Account.$$resource.fetch(this.id.toString(), 'compose').then(function(data) {
Account.$log.debug('New message: ' + JSON.stringify(data, undefined, 2));
Account.$log.debug('New message (compose): ' + JSON.stringify(data, undefined, 2));
var message = new Account.$Message(data.accountId, _this.$getMailboxByPath(data.mailboxPath), data);
return message;
}).then(function(message) {
// Fetch draft initial data
return Account.$$resource.fetch(message.$absolutePath({asDraft: true}), 'edit').then(function(data) {
Account.$log.debug('New message: ' + JSON.stringify(data, undefined, 2));
Account.$log.debug('New message (edit): ' + JSON.stringify(data, undefined, 2));
angular.extend(message.editable, data);
return message;
});
@@ -413,7 +413,22 @@
* @returns a promise of the HTTP operation
*/
Mailbox.prototype.$emptyTrash = function() {
return Mailbox.$$resource.post(this.id, 'emptyTrash');
var _this = this,
deferred = Mailbox.$q.defer(),
promise;
promise = Mailbox.$$resource.post(this.id, 'emptyTrash');
promise.then(function() {
// Remove all messages from the mailbox
_this.$messages = [];
_this.uidsMap = {};
_this.unseenCount = 0;
}, function(data, status) {
deferred.reject(data);
});
return deferred.promise;
};
/**
@@ -426,6 +441,20 @@
return Mailbox.$$resource.post(this.id, 'markRead');
};
/**
* @function $flagMessages
* @memberof Mailbox.prototype
* @desc Add or remove a flag on a message set
* @returns a promise of the HTTP operation
*/
Mailbox.prototype.$flagMessages = function(uids, flags, operation) {
var data = {msgUIDs: uids,
flags: flags,
operation: operation};
return Mailbox.$$resource.post(this.id, 'addOrRemoveLabel', data);
};
/**
* @function $delete
* @memberof Mailbox.prototype
@@ -22,6 +22,8 @@
vm.copySelectedMessages = copySelectedMessages;
// vm.moveSelectedMessages = moveSelectedMessages;
vm.saveSelectedMessages = saveSelectedMessages;
vm.markSelectedMessagesAsFlagged = markSelectedMessagesAsFlagged;
vm.markSelectedMessagesAsUnread = markSelectedMessagesAsUnread;
vm.selectAll = selectAll;
vm.sort = sort;
vm.sortedBy = sortedBy;
@@ -45,7 +47,10 @@
var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { return message.selected; });
var selectedUIDs = _.pluck(selectedMessages, 'uid');
vm.selectedFolder.$deleteMessages(selectedUIDs).then(function() {
// Decrement the unseenCount accordingly
var unseenCount = _.filter(selectedMessages, function(message) { return !message.isread; });
vm.selectedFolder.$messages = _.difference(vm.selectedFolder.$messages, selectedMessages);
vm.selectedFolder.unseenCount =- unseenCount;
}, function(error) {
Dialog.alert(l('Error'), error);
});
@@ -83,6 +88,31 @@
});
}
function markSelectedMessagesAsFlagged() {
var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { return message.selected; });
var selectedUIDs = _.pluck(selectedMessages, 'uid');
vm.selectedFolder.$flagMessages(selectedUIDs, '\\Flagged', 'add').then(function(d) {
// Success
_.forEach(selectedMessages, function(message) {
message.isflagged = true;
});
});
}
function markSelectedMessagesAsUnread() {
var selectedMessages = _.filter(vm.selectedFolder.$messages, function(message) { return message.selected; });
var selectedUIDs = _.pluck(selectedMessages, 'uid');
vm.selectedFolder.$flagMessages(selectedUIDs, 'seen', 'remove').then(function(d) {
// Success
_.forEach(selectedMessages, function(message) {
message.isread = false;
vm.selectedFolder.unseenCount++;
});
});
}
function sort(field) {
vm.selectedFolder.$filter({ sort: field });
}
@@ -97,17 +127,20 @@
}
function newMessage($event) {
var message = vm.account.$newMessage();
$mdDialog.show({
parent: angular.element(document.body),
targetEvent: $event,
clickOutsideToClose: true,
escapeToClose: true,
clickOutsideToClose: false,
escapeToClose: false,
templateUrl: 'UIxMailEditor',
controller: 'MessageEditorController',
controllerAs: 'editor',
locals: {
stateAccounts: vm.accounts,
stateMessage: vm.account.$newMessage()
stateMessage: message,
stateRecipients: []
}
});
}
@@ -177,6 +177,7 @@
var _this = this,
parts = [],
_visit = function(part) {
part.msgclass = 'msg-attachment-other';
if (part.type == 'UIxMailPartAlternativeViewer') {
_visit(_.find(part.content, function(alternatePart) {
return part.preferredPart == alternatePart.contentType;
@@ -231,6 +232,9 @@
});
}
if (part.type == 'UIxMailPartImageViewer')
part.msgclass = 'msg-attachment-image';
// Trusted content that can be compiled (Angularly-speaking)
part.compile = true;
parts.push(part);
@@ -21,6 +21,7 @@
vm.replyAll = replyAll;
vm.forward = forward;
vm.edit = edit;
vm.newMessage = newMessage;
vm.viewRawSource = viewRawSource;
// Watch the message model "flags" attribute to remove on-the-fly a tag from the IMAP message
@@ -46,7 +47,11 @@
});
}
function showMailEditor($event, message) {
function showMailEditor($event, message, recipients) {
if (!angular.isDefined(recipients))
recipients = [];
$mdDialog.show({
parent: angular.element(document.body),
targetEvent: $event,
@@ -57,7 +62,8 @@
controllerAs: 'editor',
locals: {
stateAccounts: vm.accounts,
stateMessage: message
stateMessage: message,
stateRecipients: recipients
}
});
}
@@ -83,6 +89,12 @@
});
}
function newMessage($event, recipient) {
var message = vm.account.$newMessage();
showMailEditor($event, message, [recipient]);
}
function viewRawSource($event) {
Message.$$resource.post(vm.message.id, "viewsource").then(function(data) {
$mdDialog.show({
@@ -6,8 +6,8 @@
/**
* @ngInject
*/
MessageEditorController.$inject = ['$stateParams', '$state', '$q', '$mdDialog', 'FileUploader', 'stateAccounts', 'stateMessage', '$timeout', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox', 'AddressBook', 'Preferences'];
function MessageEditorController($stateParams, $state, $q, $mdDialog, FileUploader, stateAccounts, stateMessage, $timeout, encodeUriFilter, focus, Dialog, Account, Mailbox, AddressBook, Preferences) {
MessageEditorController.$inject = ['$stateParams', '$state', '$q', '$mdDialog', 'FileUploader', 'stateAccounts', 'stateMessage', 'stateRecipients', '$timeout', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox', 'AddressBook', 'Preferences'];
function MessageEditorController($stateParams, $state, $q, $mdDialog, FileUploader, stateAccounts, stateMessage, stateRecipients, $timeout, encodeUriFilter, focus, Dialog, Account, Mailbox, AddressBook, Preferences) {
var vm = this;
vm.autocomplete = {to: {}, cc: {}, bcc: {}};
@@ -66,6 +66,10 @@
vm.message = stateMessage;
}
if (angular.isDefined(stateRecipients)) {
vm.message.editable.to = _.union(vm.message.editable.to, _.pluck(stateRecipients, 'full'));
}
function cancel() {
// TODO: delete draft?
if (vm.autosave)
@@ -104,6 +108,7 @@
Preferences.ready().then(function() {
if (Preferences.defaults.SOGoMailAutoSave)
vm.autosave = $timeout(vm.autosaveDrafts, Preferences.defaults.SOGoMailAutoSave*1000*60);
vm.localeCode = Preferences.defaults.LocaleCode;
});
}
-38
View File
@@ -1,38 +0,0 @@
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* JavaScript for MainUI (SOGoRootPage) */
(function() {
'use strict';
angular.module('SOGo.MainUI', ['SOGo.Common', 'SOGo.Authentication'])
.controller('loginController', loginController);
loginController.$inject = ['$scope', '$mdDialog', 'Authentication'];
function loginController($scope, $mdDialog, Authentication) {
$scope.warning = false;
$scope.creds = { username: cookieUsername, password: null };
$scope.login = function(creds) {
$scope.warning = false;
Authentication.login(creds)
.then(function(url) {
window.location.href = url;
}, function(msg) {
$scope.warning = msg.error;
});
return false;
};
$scope.showAbout = function($event) {
$mdDialog.show({
targetEvent: $event,
templateUrl: 'aboutBox.html',
controller: AboutDialogController
});
AboutDialogController.$inject = ['scope', '$mdDialog'];
function AboutDialogController(scope, $mdDialog) {
scope.closeDialog = function() {
$mdDialog.hide();
};
}
};
}
})();
+2
View File
@@ -0,0 +1,2 @@
!function(){"use strict";function LoginController($scope,Dialog,$mdDialog,Authentication){function login(){return Authentication.login(vm.creds).then(function(url){window.location.href=url},function(msg){Dialog.alert(l("Authentication Failed"),msg.error)}),!1}function showAbout($event){function AboutDialogController($mdDialog){this.closeDialog=function(){$mdDialog.hide()}}$mdDialog.show({targetEvent:$event,templateUrl:"aboutBox.html",controller:AboutDialogController,controllerAs:"about"}),AboutDialogController.$inject=["$mdDialog"]}var vm=this;vm.creds={username:cookieUsername,password:null},vm.login=login,vm.showAbout=showAbout}angular.module("SOGo.MainUI",["SOGo.Common","SOGo.Authentication"]),LoginController.$inject=["$scope","Dialog","$mdDialog","Authentication"],angular.module("SOGo.MainUI").controller("LoginController",LoginController)}();
//# sourceMappingURL=Main.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Main.js","sources":["Main/Main.app.js"],"names":["LoginController","$scope","Dialog","$mdDialog","Authentication","login","vm","creds","then","url","window","location","href","msg","alert","l","error","showAbout","$event","AboutDialogController","this","closeDialog","hide","show","targetEvent","templateUrl","controller","controllerAs","$inject","username","cookieUsername","password","angular","module"],"mappings":"CAGA,WACE,YAQA,SAASA,iBAAgBC,OAAQC,OAAQC,UAAWC,gBAOlD,QAASC,SAOP,MANAD,gBAAeC,MAAMC,GAAGC,OACrBC,KAAK,SAASC,KACbC,OAAOC,SAASC,KAAOH,KACtB,SAASI,KACVX,OAAOY,MAAMC,EAAE,yBAA0BF,IAAIG,UAE1C,EAGT,QAASC,WAAUC,QAQjB,QAASC,uBAAsBhB,WAC7BiB,KAAKC,YAAc,WACjBlB,UAAUmB,QATdnB,UAAUoB,MACRC,YAAaN,OACbO,YAAa,gBACbC,WAAYP,sBACZQ,aAAc,UAEhBR,sBAAsBS,SAAW,aAvBnC,GAAItB,IAAKc,IAETd,IAAGC,OAAUsB,SAAUC,eAAgBC,SAAU,MACjDzB,GAAGD,MAAQA,MACXC,GAAGW,UAAYA,UAXjBe,QAAQC,OAAO,eAAgB,cAAe,wBAK9CjC,gBAAgB4B,SAAW,SAAU,SAAU,YAAa,kBAkC5DI,QACGC,OAAO,eACPP,WAAW,kBAAmB1B","sourcesContent":["/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n/* JavaScript for MainUI (SOGoRootPage) */\n\n(function() {\n 'use strict';\n\n angular.module('SOGo.MainUI', ['SOGo.Common', 'SOGo.Authentication']);\n\n /**\n * @ngInject\n */\n LoginController.$inject = ['$scope', 'Dialog', '$mdDialog', 'Authentication'];\n function LoginController($scope, Dialog, $mdDialog, Authentication) {\n var vm = this;\n\n vm.creds = { username: cookieUsername, password: null };\n vm.login = login;\n vm.showAbout = showAbout;\n\n function login() {\n Authentication.login(vm.creds)\n .then(function(url) {\n window.location.href = url;\n }, function(msg) {\n Dialog.alert(l('Authentication Failed'), msg.error);\n });\n return false;\n }\n\n function showAbout($event) {\n $mdDialog.show({\n targetEvent: $event,\n templateUrl: 'aboutBox.html',\n controller: AboutDialogController,\n controllerAs: 'about'\n });\n AboutDialogController.$inject = ['$mdDialog'];\n function AboutDialogController($mdDialog) {\n this.closeDialog = function() {\n $mdDialog.hide();\n };\n }\n }\n }\n\n angular\n .module('SOGo.MainUI')\n .controller('LoginController', LoginController);\n})();\n"]}
+49
View File
@@ -0,0 +1,49 @@
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* JavaScript for MainUI (SOGoRootPage) */
(function() {
'use strict';
angular.module('SOGo.MainUI', ['SOGo.Common', 'SOGo.Authentication']);
/**
* @ngInject
*/
LoginController.$inject = ['$scope', 'Dialog', '$mdDialog', 'Authentication'];
function LoginController($scope, Dialog, $mdDialog, Authentication) {
var vm = this;
vm.creds = { username: cookieUsername, password: null };
vm.login = login;
vm.showAbout = showAbout;
function login() {
Authentication.login(vm.creds)
.then(function(url) {
window.location.href = url;
}, function(msg) {
Dialog.alert(l('Authentication Failed'), msg.error);
});
return false;
}
function showAbout($event) {
$mdDialog.show({
targetEvent: $event,
templateUrl: 'aboutBox.html',
controller: AboutDialogController,
controllerAs: 'about'
});
AboutDialogController.$inject = ['$mdDialog'];
function AboutDialogController($mdDialog) {
this.closeDialog = function() {
$mdDialog.hide();
};
}
}
}
angular
.module('SOGo.MainUI')
.controller('LoginController', LoginController);
})();
+2
View File
@@ -0,0 +1,2 @@
!function(){"use strict";function configure($stateProvider,$urlRouterProvider){$stateProvider.state("preferences",{"abstract":!0,views:{preferences:{templateUrl:"preferences.html",controller:"PreferencesController",controllerAs:"app"}},resolve:{statePreferences:statePreferences}}).state("preferences.general",{url:"/general",views:{module:{templateUrl:"generalPreferences.html"}}}).state("preferences.calendars",{url:"/calendars",views:{module:{templateUrl:"calendarsPreferences.html"}}}).state("preferences.addressbooks",{url:"/addressbooks",views:{module:{templateUrl:"addressbooksPreferences.html"}}}).state("preferences.mailer",{url:"/mailer",views:{module:{templateUrl:"mailerPreferences.html"}}}),$urlRouterProvider.otherwise("/general")}function statePreferences(Preferences){return Preferences}function runBlock($rootScope){$rootScope.$on("$routeChangeError",function(event,current,previous,rejection){console.error(event,current,previous,rejection)})}angular.module("SOGo.PreferencesUI",["ngSanitize","ui.router","ck","SOGo.Common","SOGo.MailerUI","SOGo.ContactsUI","SOGo.Authentication"]).config(configure).run(runBlock),configure.$inject=["$stateProvider","$urlRouterProvider"],statePreferences.$inject=["Preferences"],runBlock.$inject=["$rootScope"]}(),function(){"use strict";function AccountDialogController($mdDialog,defaults,account,accountId,mailCustomFromEnabled){function customFromIsReadonly(){return accountId>0?!1:!mailCustomFromEnabled}function cancel(){$mdDialog.cancel()}function save(){$mdDialog.hide()}var vm=this;vm.defaults=defaults,vm.account=account,vm.accountId=accountId,vm.customFromIsReadonly=customFromIsReadonly,vm.cancel=cancel,vm.save=save}AccountDialogController.$inject=["$mdDialog","defaults","account","accountId","mailCustomFromEnabled"],angular.module("SOGo.PreferencesUI").controller("AccountDialogController",AccountDialogController)}(),function(){"use strict";function FiltersDialogController($scope,$mdDialog,filter,mailboxes,labels){$scope.filter=filter,$scope.mailboxes=mailboxes,$scope.labels=labels,$scope.fieldLabels={subject:l("Subject"),from:l("From"),to:l("To"),cc:l("Cc"),to_or_cc:l("To or Cc"),size:l("Size (Kb)"),header:l("Header"),body:l("Body")},$scope.methodLabels={addflag:l("Flag the message with:"),discard:l("Discard the message"),fileinto:l("File the message in:"),keep:l("Keep the message"),redirect:l("Forward the message to:"),reject:l("Send a reject message:"),vacation:l("Send a vacation message"),stop:l("Stop processing filter rules")},$scope.numberOperatorLabels={under:l("is under"),over:l("is over")},$scope.textOperatorLabels={is:l("is"),is_not:l("is not"),contains:l("contains"),contains_not:l("does not contain"),matches:l("matches"),matches_not:l("does not match"),regex:l("matches regex"),regex_not:l("does not match regex")},$scope.flagLabels={seen:l("Seen"),deleted:l("Deleted"),answered:l("Answered"),flagged:l("Flagged"),junk:l("Junk"),not_junk:l("Not Junk")},$scope.cancel=function(){$mdDialog.cancel()},$scope.save=function(){$mdDialog.hide()},$scope.addMailFilterRule=function(event){$scope.filter.rules||($scope.filter.rules=[]),$scope.filter.rules.push({})},$scope.removeMailFilterRule=function(index){$scope.filter.rules.splice(index,1)},$scope.addMailFilterAction=function(event){$scope.filter.actions||($scope.filter.actions=[]),$scope.filter.actions.push({})},$scope.removeMailFilterAction=function(index){$scope.filter.actions.splice(index,1)}}FiltersDialogController.$inject=["$scope","$mdDialog","filter","mailboxes","labels"],angular.module("SOGo.PreferencesUI").controller("FiltersDialogController",FiltersDialogController)}(),function(){"use strict";function PreferencesController($state,$mdDialog,User,Mailbox,statePreferences,Authentication){function go(module){$state.go("preferences."+module)}function addCalendarCategory(){vm.preferences.defaults.SOGoCalendarCategoriesColors["New category"]="#aaa",vm.preferences.defaults.SOGoCalendarCategories.push("New category")}function removeCalendarCategory(index){var key=vm.preferences.defaults.SOGoCalendarCategories[index];vm.preferences.defaults.SOGoCalendarCategories.splice(index,1),delete vm.preferences.defaults.SOGoCalendarCategoriesColors[key]}function addContactCategory(){vm.preferences.defaults.SOGoContactsCategories.push("")}function removeContactCategory(index){vm.preferences.defaults.SOGoContactsCategories.splice(index,1)}function addMailAccount(ev){var account;vm.preferences.defaults.AuxiliaryMailAccounts.push({}),account=_.last(vm.preferences.defaults.AuxiliaryMailAccounts),account.name=l("New account"),account.identities=[{fullName:"",email:""}],account.receipts={receiptAction:"ignore",receiptNonRecipientAction:"ignore",receiptOutsideDomainAction:"ignore",receiptAnyAction:"ignore"},$mdDialog.show({controller:"AccountDialogController",controllerAs:"$AccountDialogController",templateUrl:"editAccount?account=new",targetEvent:ev,locals:{defaults:vm.preferences.defaults,account:account,accountId:vm.preferences.defaults.ALine truncated
//# sourceMappingURL=Preferences.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Preferences.js","sources":["Preferences/Preferences.app.js","Preferences/AccountDialogController.js","Preferences/FiltersDialogController.js","Preferences/PreferencesController.js"],"names":["configure","$stateProvider","$urlRouterProvider","state","abstract","views","preferences","templateUrl","controller","controllerAs","resolve","statePreferences","url","module","otherwise","Preferences","runBlock","$rootScope","$on","event","current","previous","rejection","console","error","angular","config","run","$inject","AccountDialogController","$mdDialog","defaults","account","accountId","mailCustomFromEnabled","customFromIsReadonly","cancel","save","hide","vm","this","FiltersDialogController","$scope","filter","mailboxes","labels","fieldLabels","subject","l","from","to","cc","to_or_cc","size","header","body","methodLabels","addflag","discard","fileinto","keep","redirect","reject","vacation","stop","numberOperatorLabels","under","over","textOperatorLabels","is","is_not","contains","contains_not","matches","matches_not","regex","regex_not","flagLabels","seen","deleted","answered","flagged","junk","not_junk","addMailFilterRule","rules","push","removeMailFilterRule","index","splice","addMailFilterAction","actions","removeMailFilterAction","PreferencesController","$state","User","Mailbox","Authentication","go","addCalendarCategory","SOGoCalendarCategoriesColors","SOGoCalendarCategories","removeCalendarCategory","key","addContactCategory","SOGoContactsCategories","removeContactCategory","addMailAccount","ev","AuxiliaryMailAccounts","_","last","name","identities","fullName","email","receipts","receiptAction","receiptNonRecipientAction","receiptOutsideDomainAction","receiptAnyAction","show","targetEvent","locals","length","window","editMailAccount","then","removeMailAccount","addMailLabel","SOGoMailLabelsColors","new_label","removeMailLabel","addMailFilter","SOGoSieveFilters","editMailFilter","copy","removeMailFilter","$save","canChangePassword","passwords","newPassword","newPasswordConfirmation","changePassword","alert","title","content","ok","undefined","msg","timeZonesListFilter","timeZonesList","value","toUpperCase","indexOf","userFilter","$filter","timeZonesSearchText","$find","id"],"mappings":"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 truncated
@@ -0,0 +1,2 @@
!function(){"use strict";function Preferences(){var _this=this;this.defaults={},this.settings={},this.defaultsPromise=Preferences.$$resource.fetch("jsonDefaults").then(function(data){var labels=_.object(_.map(data.SOGoMailLabelsColors,function(value,key){return"$"==key.charAt(0)?["_"+key,value]:[key,value]}));return data.SOGoMailLabelsColors=labels,data.Vacation&&data.Vacation.autoReplyEmailAddresses&&(data.Vacation.autoReplyEmailAddresses=data.Vacation.autoReplyEmailAddresses.join(",")),data.Forward&&data.Forward.forwardAddress&&(data.Forward.forwardAddress=data.Forward.forwardAddress.join(",")),angular.extend(_this.defaults,data),_this.defaults}),this.settingsPromise=Preferences.$$resource.fetch("jsonSettings").then(function(data){return data.Calendar&&data.Calendar.PreventInvitationsWhitelist?data.Calendar.PreventInvitationsWhitelist=_.map(data.Calendar.PreventInvitationsWhitelist,function(value,key){var match=/^(.+)\s<(\S+)>$/.exec(value);return new Preferences.$User({uid:key,cn:match[1],c_email:match[2]})}):data.Calendar.PreventInvitationsWhitelist=[],angular.extend(_this.settings,data),_this.settings})}Preferences.$factory=["$q","$timeout","$log","sgSettings","Resource","User",function($q,$timeout,$log,Settings,Resource,User){return angular.extend(Preferences,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL"),Settings.activeUser()),activeUser:Settings.activeUser(),$User:User}),new Preferences}];try{angular.module("SOGo.PreferencesUI")}catch(e){angular.module("SOGo.PreferencesUI",["SOGo.Common"])}angular.module("SOGo.PreferencesUI").factory("Preferences",Preferences.$factory),Preferences.prototype.ready=function(){return Preferences.$q.all([this.defaultsPromise,this.settingsPromise])},Preferences.prototype.$save=function(){return Preferences.$$resource.save("Preferences",this.$omit(!0)).then(function(data){return data})},Preferences.prototype.$omit=function(deep){var preferences={};angular.forEach(this,function(value,key){"constructor"!=key&&"$"!=key[0]&&(deep?preferences[key]=angular.copy(value):preferences[key]=value)});var labels=_.object(_.map(preferences.defaults.SOGoMailLabelsColors,function(value,key){return"_"==key.charAt(0)&&"$"==key.charAt(1)?[key.substring(1),value]:[key,value]}));if(preferences.defaults.SOGoMailLabelsColors=labels,preferences.defaults.Vacation&&preferences.defaults.Vacation.autoReplyEmailAddresses&&(preferences.defaults.Vacation.autoReplyEmailAddresses=preferences.defaults.Vacation.autoReplyEmailAddresses.split(",")),preferences.defaults.Forward&&preferences.defaults.Forward.forwardAddress&&(preferences.defaults.Forward.forwardAddress=preferences.defaults.Forward.forwardAddress.split(",")),preferences.settings.Calendar&&preferences.settings.Calendar.PreventInvitationsWhitelist){var h={};_.each(preferences.settings.Calendar.PreventInvitationsWhitelist,function(user){h[user.uid]=user.$shortFormat()}),preferences.settings.Calendar.PreventInvitationsWhitelist=h}return preferences}}();
//# sourceMappingURL=Preferences.services.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Preferences.services.js","sources":["Preferences/Preferences.service.js"],"names":["Preferences","_this","this","defaults","settings","defaultsPromise","$$resource","fetch","then","data","labels","_","object","map","SOGoMailLabelsColors","value","key","charAt","Vacation","autoReplyEmailAddresses","join","Forward","forwardAddress","angular","extend","settingsPromise","Calendar","PreventInvitationsWhitelist","match","exec","$User","uid","cn","c_email","$factory","$q","$timeout","$log","Settings","Resource","User","activeUser","module","e","factory","prototype","ready","all","$save","save","$omit","deep","preferences","forEach","copy","substring","split","h","each","user","$shortFormat"],"mappings":"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","sourcesContent":["/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Preferences\n * @constructor\n */\n function Preferences() {\n var _this = this;\n\n this.defaults = {};\n this.settings = {};\n\n this.defaultsPromise = Preferences.$$resource.fetch(\"jsonDefaults\").then(function(data) {\n // We swap $key -> _$key to avoid an Angular bug (https://github.com/angular/angular.js/issues/6266)\n var labels = _.object(_.map(data.SOGoMailLabelsColors, function(value, key) {\n if (key.charAt(0) == '$')\n return ['_' + key, value];\n return [key, value];\n }));\n\n data.SOGoMailLabelsColors = labels;\n\n // We convert our list of autoReplyEmailAddresses/forwardAddress into a string.\n if (data.Vacation && data.Vacation.autoReplyEmailAddresses)\n data.Vacation.autoReplyEmailAddresses = data.Vacation.autoReplyEmailAddresses.join(\",\");\n\n if (data.Forward && data.Forward.forwardAddress)\n data.Forward.forwardAddress = data.Forward.forwardAddress.join(\",\");\n\n angular.extend(_this.defaults, data);\n\n return _this.defaults;\n });\n\n this.settingsPromise = Preferences.$$resource.fetch(\"jsonSettings\").then(function(data) {\n // We convert our PreventInvitationsWhitelist hash into a array of user\n if (data.Calendar && data.Calendar.PreventInvitationsWhitelist)\n data.Calendar.PreventInvitationsWhitelist = _.map(data.Calendar.PreventInvitationsWhitelist, function(value, key) {\n var match = /^(.+)\\s<(\\S+)>$/.exec(value);\n return new Preferences.$User({uid: key, cn: match[1], c_email: match[2]});\n });\n else\n data.Calendar.PreventInvitationsWhitelist = [];\n\n angular.extend(_this.settings, data);\n\n return _this.settings;\n });\n }\n\n /**\n * @memberof Preferences\n * @desc The factory we'll use to register with Angular\n * @returns the Preferences constructor\n */\n Line truncated
@@ -7,22 +7,31 @@
/**
* @ngInject
*/
AccountDialogController.$inject = ['$scope', '$mdDialog', 'account', 'accountId', 'mailCustomFromEnabled'];
function AccountDialogController($scope, $mdDialog, account, accountId, mailCustomFromEnabled) {
$scope.account = account;
$scope.accountId = accountId;
$scope.customFromIsReadonly = function() {
AccountDialogController.$inject = ['$mdDialog', 'defaults', 'account', 'accountId', 'mailCustomFromEnabled'];
function AccountDialogController($mdDialog, defaults, account, accountId, mailCustomFromEnabled) {
var vm = this;
vm.defaults = defaults;
vm.account = account;
vm.accountId = accountId;
vm.customFromIsReadonly = customFromIsReadonly;
vm.cancel = cancel;
vm.save = save;
function customFromIsReadonly() {
if (accountId > 0)
return false;
return !mailCustomFromEnabled;
};
$scope.cancel = function() {
}
function cancel() {
$mdDialog.cancel();
};
$scope.save = function() {
}
function save() {
$mdDialog.hide();
};
}
}
angular
@@ -4,7 +4,7 @@
(function() {
'use strict';
angular.module('SOGo.PreferencesUI', ['ngSanitize', 'ui.router', 'SOGo.Common', 'SOGo.MailerUI', 'SOGo.ContactsUI', 'SOGo.Authentication'])
angular.module('SOGo.PreferencesUI', ['ngSanitize', 'ui.router', 'ck', 'SOGo.Common', 'SOGo.MailerUI', 'SOGo.ContactsUI', 'SOGo.Authentication'])
.config(configure)
.run(runBlock);
@@ -63,23 +63,29 @@
var account;
vm.preferences.defaults.AuxiliaryMailAccounts.push({});
account = _.last(vm.preferences.defaults.AuxiliaryMailAccounts);
account.name = "New account";
account.identities = [];
account.identities[0] = {};
account.identities[0].fullName = "";
account.identities[0].email = "";
account.receipts = {};
account.receipts.receiptAction = "ignore";
account.receipts.receiptNonRecipientAction = "ignore";
account.receipts.receiptOutsideDomainAction = "ignore";
account.receipts.receiptAnyAction = "ignore";
account.name = l("New account");
account.identities = [
{
fullName: "",
email: ""
}
];
account.receipts = {
receiptAction: "ignore",
receiptNonRecipientAction: "ignore",
receiptOutsideDomainAction: "ignore",
receiptAnyAction: "ignore"
};
$mdDialog.show({
controller: 'AccountDialogController',
controllerAs: '$AccountDialogController',
templateUrl: 'editAccount?account=new',
targetEvent: ev,
locals: {
defaults: vm.preferences.defaults,
account: account,
accountId: (vm.preferences.defaults.AuxiliaryMailAccounts.length-1),
mailCustomFromEnabled: window.mailCustomFromEnabled
@@ -87,13 +93,15 @@
});
}
function editMailAccount(index) {
function editMailAccount(event, index) {
var account = vm.preferences.defaults.AuxiliaryMailAccounts[index];
$mdDialog.show({
controller: 'AccountDialogController',
controllerAs: '$AccountDialogController',
templateUrl: 'editAccount?account=' + index,
targetEvent: null,
targetEvent: event,
locals: {
defaults: vm.preferences.defaults,
account: account,
accountId: index,
mailCustomFromEnabled: window.mailCustomFromEnabled
+2
View File
@@ -0,0 +1,2 @@
!function(){"use strict";function configure($stateProvider,$urlRouterProvider){$stateProvider.state("calendars",{url:"/calendar",views:{calendars:{templateUrl:"UIxCalMainFrame",controller:"CalendarsController",controllerAs:"calendars"}},resolve:{stateCalendars:stateCalendars}}).state("calendars.view",{url:"/{view:(?:day|week|month)}/:day",sticky:!0,deepStateRedirect:!0,views:{calendarView:{templateUrl:function($stateParams){return $stateParams.view+"view?day="+$stateParams.day},controller:"CalendarController",controllerAs:"calendar"}},resolve:{stateEventsBlocks:stateEventsBlocks}}),$urlRouterProvider.when("/calendar/day",function(){var now=new Date;return"/calendar/day/"+now.getDayString()}),$urlRouterProvider.when("/calendar/week",function(){var now=new Date;return"/calendar/week/"+now.getDayString()}),$urlRouterProvider.when("/calendar/month",function(){var now=new Date;return"/calendar/month/"+now.getDayString()}),$urlRouterProvider.otherwise("/calendar")}function stateCalendars(Calendar){return Calendar.$calendars||Calendar.$findAll(window.calendarsData)}function stateEventsBlocks($stateParams,Component){return Component.$eventsBlocksForView($stateParams.view,$stateParams.day.asDate())}function runBlock($rootScope,$location,Preferences){$rootScope.$on("$routeChangeError",function(event,current,previous,rejection){console.error(event,current,previous,rejection)}),0===$location.url().length&&Preferences.ready().then(function(){var view=/(.+)view/.exec(Preferences.settings.Calendar.View);view&&$location.replace().url("/calendar/"+view[1])})}angular.module("SOGo.SchedulerUI",["ngSanitize","ui.router","SOGo.Common","SOGo.PreferencesUI","SOGo.ContactsUI","SOGo.MailerUI"]).config(configure).run(runBlock),configure.$inject=["$stateProvider","$urlRouterProvider"],stateCalendars.$inject=["Calendar"],stateEventsBlocks.$inject=["$stateParams","Component"],runBlock.$inject=["$rootScope","$location","Preferences"]}(),function(){"use strict";function CalendarController($scope,$state,$stateParams,$timeout,$interval,$log,focus,Calendar,Component,stateEventsBlocks){function changeView($event){var date=angular.element($event.currentTarget).attr("date");$state.go("calendars.view",{view:$stateParams.view,day:date})}var vm=this;vm.blocks=stateEventsBlocks,vm.changeView=changeView,$scope.$on("calendars:list",function(){Component.$eventsBlocksForView($stateParams.view,$stateParams.day.asDate()).then(function(data){vm.blocks=data})})}CalendarController.$inject=["$scope","$state","$stateParams","$timeout","$interval","$log","sgFocus","Calendar","Component","stateEventsBlocks"],angular.module("SOGo.SchedulerUI").controller("CalendarController",CalendarController)}(),function(){"use strict";function CalendarListController($scope,$timeout,$state,$mdDialog,encodeUriFilter,Dialog,Preferences,Calendar,Component){function selectComponentType(type,options){(options&&options.reload||vm.componentType!=type)&&(angular.isUndefined(Component["$"+type])&&Component.$filter(type),vm.componentType=type,Component.saveSelectedList(type))}function openEvent($event,event){openComponent($event,event,"appointment")}function openTask($event,task){openComponent($event,task,"task")}function openComponent($event,component,type){var templateUrl="UIx"+type.capitalize()+"ViewTemplate";$mdDialog.show({parent:angular.element(document.body),targetEvent:$event,clickOutsideToClose:!0,escapeToClose:!0,templateUrl:templateUrl,controller:"ComponentController",controllerAs:"editor",locals:{stateComponent:component}})}function newComponent($event){var component,type="appointment";"tasks"==vm.componentType&&(type="task"),component=new Component({pid:"personal",type:type});var templateUrl="UIx"+type.capitalize()+"EditorTemplate";$mdDialog.show({parent:angular.element(document.body),targetEvent:$event,clickOutsideToClose:!0,escapeToClose:!0,templateUrl:templateUrl,controller:"ComponentEditorController",controllerAs:"editor",locals:{stateComponent:component}})}function filter(filterpopup){Component.$filter(vm.componentType,{filterpopup:filterpopup})}function filteredBy(filterpopup){return Component["$query"+vm.componentType.capitalize()].filterpopup==filterpopup}function sort(field){Component.$filter(vm.componentType,{sort:field})}function sortedBy(field){return Component["$query"+vm.componentType.capitalize()].sort==field}function cancelSearch(){vm.mode.search=!1,Component.$filter(vm.componentType,{value:""})}var vm=this;vm.component=Component,vm.componentType="events",vm.selectedList=0,vm.selectComponentType=selectComponentType,vm.openEvent=openEvent,vm.openTask=openTask,vm.newComponent=newComponent,vm.filter=filter,vm.filteredBy=filteredBy,vm.sort=sort,vm.sortedBy=sortedBy,vm.cancelSearch=cancelSearch,vm.mode={search:!1},Preferences.ready().then(function(){var type="events";"tasksListView"==Preferences.settings.Calendar.SelectedList&&(vm.selectedList=1,type="tasks"),selectComponentType(type,{reload:!0})}),$scope.$on("calendars:list",function(){Component.$filter(vm.comLine truncated
//# sourceMappingURL=Scheduler.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Scheduler.js","sources":["Scheduler/Scheduler.app.js","Scheduler/CalendarController.js","Scheduler/CalendarListController.js","Scheduler/CalendarsController.js","Scheduler/ComponentController.js","Scheduler/sgCalendarDayBlock.directive.js","Scheduler/sgCalendarDayTable.directive.js","Scheduler/sgCalendarMonthDay.directive.js","Scheduler/sgCalendarMonthEvent.directive.js"],"names":["configure","$stateProvider","$urlRouterProvider","state","url","views","calendars","templateUrl","controller","controllerAs","resolve","stateCalendars","sticky","deepStateRedirect","calendarView","$stateParams","view","day","stateEventsBlocks","when","now","Date","getDayString","otherwise","Calendar","$calendars","$findAll","window","calendarsData","Component","$eventsBlocksForView","asDate","runBlock","$rootScope","$location","Preferences","$on","event","current","previous","rejection","console","error","length","ready","then","exec","settings","View","replace","angular","module","config","run","$inject","CalendarController","$scope","$state","$timeout","$interval","$log","focus","changeView","$event","date","element","currentTarget","attr","go","vm","this","blocks","data","CalendarListController","$mdDialog","encodeUriFilter","Dialog","selectComponentType","type","options","reload","componentType","isUndefined","$filter","saveSelectedList","openEvent","openComponent","openTask","task","component","capitalize","show","parent","document","body","targetEvent","clickOutsideToClose","escapeToClose","locals","stateComponent","newComponent","pid","filter","filterpopup","filteredBy","sort","field","sortedBy","cancelSearch","mode","search","value","selectedList","SelectedList","CalendarsController","$q","Settings","User","newCalendar","ev","prompt","l","name","calendar","isEditable","isRemote","owner","UserLogin","$add","addWebCalendar","inputType","$addWebCalendar","confirmDelete","folder","isSubscription","$delete","$broadcast","status","alert","confirm","showLinks","selectedFolder","LinksDialogController","scope","close","hide","id","showProperties","PropertiesDialogController","saveProperties","$save","init","$omit","share","$acl","$users","usersWithACL","users","subscribeToFolder","calendarData","debug","$subscribe","activeUser","service","$watch","_","union","map","o","pick","$subscriptions","$webcalendars","newList","oldList","ids","pluck","i","isEqual","join","each","$get","$setActivation","ComponentController","AddressBook","Alarm","cardFilter","$query","$filterAll","$cards","edit","editAllOccurrences","$getComponent","$futureComponentData","reply","c","$reply","getAlarms","replyAllOccurrences","delegatedTo","$hasAlarm","alarm","c_folder","c_name","c_recurrence_id","organizer","ComponentEditorController","Card","addAttachUrl","toggleRecurrenceEditor","showRecurrenceEditor","$hasCustomRepeat","toggleAttendeesEditor","showAttendeesEditor","addAttendee","card","isString","isValidEmail","emails","searchText","save","form","$valid","cancel","$reset","isNew","getDays","days","start","end","daysUpTo","stringWithSeparator","getHours","hours","push","toString","categories","isDefined","attendees","attendeesEditor","startDate","endDate","newStartDate","oldStartDate","substring","freebusy","updateFreeBusyCoverage","newEndDate","oldEndDate","sgCalendarDayBlock","link","iElement","attrs","pc","block","siblings","left","position","right","css","addClass","restrict","clickBlock","template","directive","sgCalendarDayTable","sgCalendarMonthDay","sgCalendarMonthEvent"],"mappings":"CAGA,WACE,YAUA,SAASA,WAAUC,eAAgBC,oBACjCD,eACGE,MAAM,aACLC,IAAK,YACLC,OACEC,WACEC,YAAa,kBACbC,WAAY,sBACZC,aAAc,cAGlBC,SACEC,eAAgBA,kBAGnBR,MAAM,kBACLC,IAAK,kCACLQ,QAAQ,EACRC,mBAAmB,EACnBR,OACES,cACEP,YAAa,SAASQ,cAIpB,MAAOA,cAAaC,KAAO,YAAcD,aAAaE,KAExDT,WAAY,qBACZC,aAAc,aAGlBC,SACEQ,kBAAmBA,qBAIzBhB,mBAAmBiB,KAAK,gBAAiB,WAEvC,GAAIC,KAAM,GAAIC,KACd,OAAO,iBAAmBD,IAAIE,iBAEhCpB,mBAAmBiB,KAAK,iBAAkB,WAExC,GAAIC,KAAM,GAAIC,KACd,OAAO,kBAAoBD,IAAIE,iBAEjCpB,mBAAmBiB,KAAK,kBAAmB,WAEzC,GAAIC,KAAM,GAAIC,KACd,OAAO,mBAAqBD,IAAIE,iBAKlCpB,mBAAmBqB,UAAU,aAO/B,QAASZ,gBAAea,UACtB,MAAOA,UAASC,YAAcD,SAASE,SAASC,OAAOC,eAOzD,QAASV,mBAAkBH,aAAcc,WACvC,MAAOA,WAAUC,qBAAqBf,aAAaC,KAAMD,aAAaE,IAAIc,UAO5E,QAASC,UAASC,WAAYC,UAAWC,aACvCF,WAAWG,IAAI,oBAAqB,SAASC,MAAOC,QAASC,SAAUC,WACrEC,QAAQC,MAAML,MAAOC,QAASC,SAAUC,aAEX,IAA3BN,UAAU9B,MAAMuC,QAElBR,YAAYS,QAAQC,KAAK,WACvB,GAAI7B,MAAO,WAAW8B,KAAKX,YAAYY,SAASvB,SAASwB,KACrDhC,OACFkB,UAAUe,UAAU7C,IAAI,aAAeY,KAAK,MA9FpDkC,QAAQC,OAAO,oBAAqB,aAAc,YAAa,cAAe,qBAAsB,kBAAmB,kBACpHC,OAAOpD,WACPqD,IAAIrB,UAKPhC,UAAUsD,SAAW,iBAAkB,sBA6DvC3C,eAAe2C,SAAW,YAQ1BpC,kBAAkBoC,SAAW,eAAgB,aAQ7CtB,SAASsB,SAAW,aAAc,YAAa,kBCxFjD,WACE,YAMA,SAASC,oBAAmBC,OAAQC,OAAQ1C,aAAc2C,SAAUC,UAAWC,KAAMC,MAAOrC,SAAUK,UAAWX,mBAc/G,QAAS4C,YAAWC,QAClB,GAAIC,MAAOd,QAAQe,QAAQF,OAAOG,eAAeC,KAAK,OACtDV,QAAOW,GAAG,kBAAoBpD,KAAMD,aAAaC,KAAMC,IAAK+C,OAf9D,GAAIK,IAAKC,IAETD,IAAGE,OAASrD,kBACZmD,GAAGP,WAAaA,WAGhBN,OAAOpB,IAAI,iBAAkB,WAC3BP,UAAUC,qBAAqBf,aAAaC,KAAMD,aAAaE,IAAIc,ULine truncated
@@ -0,0 +1,2 @@
!function(){"use strict";function Calendar(futureCalendarData){if(this.init(futureCalendarData),this.name&&!this.id){var newCalendarData=Calendar.$$resource.create("createFolder",this.name);angular.extend(this,newCalendarData)}this.id&&(this.$acl=new Calendar.$$Acl("Calendar/"+this.id))}Calendar.$factory=["$q","$timeout","$log","sgSettings","Resource","Component","Acl",function($q,$timeout,$log,Settings,Resource,Component,Acl){return angular.extend(Calendar,{$q:$q,$timeout:$timeout,$log:$log,$$resource:new Resource(Settings.activeUser("folderURL")+"Calendar",Settings.activeUser()),$Component:Component,$$Acl:Acl,activeUser:Settings.activeUser()}),Calendar}];try{angular.module("SOGo.SchedulerUI")}catch(e){angular.module("SOGo.SchedulerUI",["SOGo.Common"])}angular.module("SOGo.SchedulerUI").factory("Calendar",Calendar.$factory),Calendar.$add=function(calendar){var list,sibling,i;list=calendar.isWebCalendar?this.$webcalendars:calendar.isSubscription?this.$subscriptions:this.$calendars,sibling=_.find(list,function(o){return"personal"!=o.id&&1===o.name.localeCompare(calendar.name)}),i=sibling?_.indexOf(_.pluck(list,"id"),sibling.id):1,list.splice(i,0,calendar)},Calendar.$findAll=function(data){var _this=this;return data&&(this.$calendars=[],this.$subscriptions=[],this.$webcalendars=[],angular.forEach(data,function(o,i){var calendar=new Calendar(o);calendar.isWebCalendar?_this.$webcalendars.push(calendar):calendar.isSubscription?_this.$subscriptions.push(calendar):_this.$calendars.push(calendar)})),this.$calendars},Calendar.$get=function(id){var calendar;return calendar=_.find(Calendar.$calendars,function(o){return o.id==id}),calendar||(calendar=_.find(Calendar.$subscriptions,function(o){return o.id==id})),calendar||(calendar=_.find(Calendar.$webcalendars,function(o){return o.id==id})),calendar},Calendar.$subscribe=function(uid,path){var _this=this;return Calendar.$$resource.userResource(uid).fetch(path,"subscribe").then(function(calendarData){var calendar=new Calendar(calendarData);return _.find(_this.$subscriptions,function(o){return o.id==calendarData.id})||Calendar.$add(calendar),calendar})},Calendar.$addWebCalendar=function(url){var _this=this,d=Calendar.$q.defer();return _.find(_this.$webcalendars,function(o){return o.urls.webCalendarURL==url})?d.reject():Calendar.$$resource.post(null,"addWebCalendar",{url:url}).then(function(calendarData){angular.extend(calendarData,{isWebCalendar:!0,isEditable:!0,isRemote:!1,owner:Calendar.activeUser.login,urls:{webCalendarURL:url}});var calendar=new Calendar(calendarData);Calendar.$add(calendar),Calendar.$$resource.fetch(calendar.id,"reload").then(function(data){Calendar.$log.debug(JSON.stringify(data,void 0,2))}),d.resolve()},function(){d.reject()}),d.promise},Calendar.prototype.init=function(data){angular.extend(this,data),this.isOwned=Calendar.activeUser.isSuperUser||this.owner==Calendar.activeUser.login,this.isSubscription=!this.isRemote&&this.owner!=Calendar.activeUser.login},Calendar.prototype.getClassName=function(base){return angular.isUndefined(base)&&(base="fg"),base+"-folder"+this.id},Calendar.prototype.$rename=function(name){var i=_.indexOf(_.pluck(Calendar.$calendars,"id"),this.id);return this.name=name,Calendar.$calendars.splice(i,1),Calendar.$add(this),this.$save()},Calendar.prototype.$delete=function(){var list,promise,_this=this,d=Calendar.$q.defer();return this.isSubscription?(promise=Calendar.$$resource.fetch(this.id,"unsubscribe"),list=Calendar.$subscriptions):(promise=Calendar.$$resource.remove(this.id),list=this.isWebCalendar?Calendar.$webcalendars:Calendar.$calendars),promise.then(function(){var i=_.indexOf(_.pluck(list,"id"),_this.id);list.splice(i,1),d.resolve()},function(data,status){d.reject(data)}),d.promise},Calendar.prototype.$save=function(){return Calendar.$$resource.save(this.id,this.$omit()).then(function(data){return data})},Calendar.prototype.$setActivation=function(){return Calendar.$$resource.fetch(this.id,(this.active?"":"de")+"activateFolder")},Calendar.prototype.$getComponent=function(componentId,recurrenceId){return Calendar.$Component.$find(this.id,componentId,recurrenceId)},Calendar.prototype.$omit=function(){var calendar={};return angular.forEach(this,function(value,key){"constructor"!=key&&"$"!=key[0]&&(calendar[key]=value)}),calendar}}(),function(){"use strict";function Component(futureComponentData){if("function"!=typeof futureComponentData.then){if(this.init(futureComponentData),this.pid&&!this.id){var newComponentData=Component.$$resource.newguid(this.pid);this.$unwrap(newComponentData),this.isNew=!0}}else this.$unwrap(futureComponentData)}Component.$factory=["$q","$timeout","$log","sgSettings","Preferences","Gravatar","Resource",function($q,$timeout,$log,Settings,Preferences,Gravatar,Resource){return angular.extend(Component,{$q:$q,$timeout:$timeout,$log:$log,$Preferences:Preferences,$gravatar:Gravatar,$$resource:new Resource(Settings.baseURL(),Settings.activeUser()),timeFormat:"%H:%M",$query:{value:"",search:"title_CateLine truncated
//# sourceMappingURL=Scheduler.services.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Scheduler.services.js","sources":["Scheduler/Calendar.service.js","Scheduler/Component.service.js"],"names":["Calendar","futureCalendarData","this","init","name","id","newCalendarData","$$resource","create","angular","extend","$acl","$$Acl","$factory","$q","$timeout","$log","Settings","Resource","Component","Acl","activeUser","$Component","module","e","factory","$add","calendar","list","sibling","i","isWebCalendar","$webcalendars","isSubscription","$subscriptions","$calendars","_","find","o","localeCompare","indexOf","pluck","splice","$findAll","data","_this","forEach","push","$get","$subscribe","uid","path","userResource","fetch","then","calendarData","$addWebCalendar","url","d","defer","urls","webCalendarURL","reject","post","isEditable","isRemote","owner","login","debug","JSON","stringify","undefined","resolve","promise","prototype","isOwned","isSuperUser","getClassName","base","isUndefined","$rename","$save","$delete","remove","status","save","$omit","$setActivation","active","$getComponent","componentId","recurrenceId","$find","value","key","futureComponentData","pid","newComponentData","newguid","$unwrap","isNew","Preferences","Gravatar","$Preferences","$gravatar","baseURL","timeFormat","$query","search","$queryEvents","sort","asc","filterpopup","$queryTasks","ready","settings","EventsFilterState","TasksFilterState","EventsSortingState","parseInt","TasksSortingState","show_completed","ShowCompletedTasks","$categories","defaults","SOGoCalendarCategoriesColors","SOGoTimeFormat","$filter","type","options","now","Date","day","getDate","month","getMonth","year","getFullYear","queryKey","capitalize","params","otherType","dirty","each","keys","isDefined","$unwrapCollection","calendarId","occurrenceId","join","filterCategories","query","re","RegExp","filter","category","saveSelectedList","componentType","$eventsBlocksForView","view","date","viewAction","startDate","endDate","beginOfWeek","setTime","getTime","addDays","setDate","setMonth","endOfWeek","$eventsBlocks","deferred","toLowerCase","sd","getDayString","ed","components","blocks","reduce","events","objects","eventData","componentData","object","eventsFields","start","c_startdate","hour","getHourString","flatten","block","component","nbr","length","$blocks","fields","invoke","categories","repeat","alarm","action","quantity","unit","reference","relation","classification","substring","end","dueDate","due","$isRecurrent","days","byDayMask","occurrence","frequency","byday","toString","interval","monthdays","months","count","until","asDate","$hasCustomRepeat","hasCustomRepeat","units","M","H","D","W","match","exec","SOGoCalendarDefaultReminder","$hasAlarm","destinationCalendar","organizer","email","$image","freebusy","updateFreeBusyCoverage","attendees","attendee","image","updateFreeBusy","b","isReadOnly","isEditableOccurrence","isInvitation","userHasRSVP","isInvitationOccurrence","enablePercentComplete","coversFreeBusy","quarter","roundedStart","roundedEnd","startQuarter","getMinutes","endQuarter","setMinutes","daysUpTo","index","hourKey","currentDay","dayKey","getHours","beginOfDay","addMinutes","sday","eday","map","c_folder","addAttendee","card","c_cn","$preferredEmail","role","c_uid","hasAttendee","emails","canRemindAttendeesByEmail","addAttachUrl","attachUrl","attachUrls","deleteAttachUrl","$reset","$shadowData","$reply","reply","delegatedTo","$futureComponentData","isError","error","formatTime","dateString","hours","minutes","copy","startTime","endTime","stringWithSeparator"],"mappings":"CAEA,WACE,YAOA,SAASA,UAASC,oBAGhB,GADAC,KAAKC,KAAKF,oBACNC,KAAKE,OAASF,KAAKG,GAAI,CAEzB,GAAIC,iBAAkBN,SAASO,WAAWC,OAAO,eAAgBN,KAAKE,KACtEK,SAAQC,OAAOR,KAAMI,iBAEnBJ,KAAKG,KACPH,KAAKS,KAAO,GAAIX,UAASY,MAAM,YAAcV,KAAKG,KAStDL,SAASa,UAAY,KAAM,WAAY,OAAQ,aAAc,WAAY,YAAa,MAAO,SAASC,GAAIC,SAAUC,KAAMC,SAAUC,SAAUC,UAAWC,KAWvJ,MAVAX,SAAQC,OAAOV,UACbc,GAAIA,GACJC,SAAUA,SACVC,KAAMA,KACNT,WAAY,GAAIW,UAASD,SAASI,WAAW,aAAe,WAAYJ,SAASI,cACjFC,WAAYH,UACZP,MAAOQ,IACPC,WAAYJ,SAASI,eAGhBrB,UAOT,KACES,QAAQc,OAAO,oBAEjB,MAAMC,GACJf,QAAQc,OAAO,oBAAqB,gBAEtCd,QAAQc,OAAO,oBACZE,QAAQ,WAAYzB,SAASa,UAOhCb,SAAS0B,KAAO,SAASC,UAEvB,GAAIC,MAAMC,QAASC,CAGjBF,MADED,SAASI,cACJ7B,KAAK8B,cACLL,SAASM,eACT/B,KAAKgC,eAELhC,KAAKiC,WAEdN,QAAUO,EAAEC,KAAKT,KAAM,SAASU,GAC9B,MAAgB,YAARA,EAAEjC,IACsC,IAAxCiC,EAAElC,KAAKmC,cAAcZ,SAASvB,QAExC0B,EAAID,QAAUO,EAAEI,QAAQJ,EAAEK,MAAMb,KAAM,MAAOC,QAAQxB,IAAM,EAC3DuB,KAAKc,OAAOZ,EAAG,EAAGH,WASpB3B,SAAS2C,SAAW,SAASC,MAC3B,GAAIC,OAAQ3C,IAgBZ,OAfI0C,QACF1C,KAAKiC,cACLjC,KAAKgC,kBACLhC,KAAK8B,iBAELvB,QAAQqC,QAAQF,KAAM,SAASN,EAAGR,GAChC,GAAIH,UAAW,GAAI3B,UAASsC,EACxBX,UAASI,cACXc,MAAMb,cAAce,KAAKpB,UAClBA,SAASM,eAChBY,MAAMX,eAAea,KAAKpB,UAE1BkB,MAAMV,WAAWY,KAAKpB,aAGrBzB,KAAKiC,YASdnC,SAASgD,KAAO,SAAS3C,IACvB,GAAIsB,SAQJ,OANAA,UAAWS,EAAEC,KAAKrC,SAASmC,WAAY,SAASG,GAAK,MAAOA,GAAEjC,IAAMA,KAC/DsB,WACHA,SAAWS,EAAEC,KAAKrC,SAASkC,eAAgB,SAASI,GAAK,MAAOA,GAAEjC,IAAMA,MACrEsB,WACHA,SAAWS,EAAEC,KAAKrC,SAASgC,cAAe,SAASM,GAAK,MAAOA,GAAEjC,IAAMA,MAElEsB,UAUT3B,SAASiD,WLine truncated
@@ -46,6 +46,7 @@
if (angular.isUndefined(Component['$' + type]))
Component.$filter(type);
vm.componentType = type;
Component.saveSelectedList(type);
}
}
@@ -45,11 +45,22 @@
// Filter paramaters specific to events
$queryEvents: { sort: 'start', asc: 1, filterpopup: 'view_next7' },
// Filter parameters specific to tasks
$queryTasks: { sort: 'status', asc: 1, filterpopup: 'view_next7' } //'view_incomplete' }
$queryTasks: { sort: 'status', asc: 1, filterpopup: 'view_incomplete' }
});
Preferences.ready().then(function() {
// Initialize filter parameters from user's settings
Component.$queryEvents.filterpopup = Preferences.settings.CalendarDefaultFilter;
if (Preferences.settings.Calendar.EventsFilterState)
Component.$queryEvents.filterpopup = Preferences.settings.Calendar.EventsFilterState;
if (Preferences.settings.Calendar.TasksFilterState)
Component.$queryTasks.filterpopup = Preferences.settings.Calendar.TasksFilterState;
if (Preferences.settings.Calendar.EventsSortingState) {
Component.$queryEvents.sort = Preferences.settings.Calendar.EventsSortingState[0];
Component.$queryEvents.asc = parseInt(Preferences.settings.Calendar.EventsSortingState[1]);
}
if (Preferences.settings.Calendar.TasksSortingState) {
Component.$queryTasks.sort = Preferences.settings.Calendar.TasksSortingState[0];
Component.$queryTasks.asc = parseInt(Preferences.settings.Calendar.TasksSortingState[1]);
}
Component.$queryTasks.show_completed = parseInt(Preferences.settings.ShowCompletedTasks);
// Initialize categories from user's defaults
Component.$categories = Preferences.defaults.SOGoCalendarCategoriesColors;
@@ -162,6 +173,16 @@
});
};
/**
* @function saveSelectedList
* @desc Save to the user's settings the currently selected list.
* @param {string} componentType - either "events" or "tasks"
* @returns a promise of the HTTP operation
*/
Component.saveSelectedList = function(componentType) {
return this.$$resource.post(null, 'saveSelectedList', { list: componentType + 'ListView' });
};
/**
* @function $eventsBlocksForView
* @desc Events blocks for a specific week
@@ -28,7 +28,7 @@
},
replace: true,
template: [
'<div class="event draggable">',
'<div class="sg-event sg-draggable">',
' <div class="eventInside" ng-click="clickBlock({clickEvent: $event, clickComponent: block.component})">',
' <div class="gradient">',
' </div>',
@@ -29,10 +29,10 @@
clickBlock: '&sgClick'
},
template: [
'<sg-calendar-day-block class="event draggable"',
' ng-repeat="block in blocks[day]"',
' sg-block="block"',
' sg-click="clickBlock({event: clickEvent, component: clickComponent})"/>'
'<sg-calendar-day-block class="sg-event draggable"',
' ng-repeat="block in blocks[day]"',
' sg-block="block"',
' sg-click="clickBlock({event: clickEvent, component: clickComponent})"/>'
].join('')
};
}
@@ -14,20 +14,22 @@
<sg-calendar-monh-day
sg-blocks="calendar.blocks"
sg-day="20150408" />
sg-day="20150408"
sg-click="open({ event: clickEvent, component: clickComponent })"/>
*/
function sgCalendarMonthDay() {
return {
restrict: 'E',
scope: {
blocks: '=sgBlocks',
day: '@sgDay'
day: '@sgDay',
clickBlock: '&sgClick'
},
replace: true,
template: [
'<sg-calendar-month-event',
' ng-repeat="block in blocks[day]"',
' sg-block="block"/>'
' sg-block="block"',
' sg-click="clickBlock({event: clickEvent, component: clickComponent})"/>'
].join('')
};
}
@@ -19,21 +19,21 @@
return {
restrict: 'E',
scope: {
block: '=sgBlock'
block: '=sgBlock',
clickBlock: '&sgClick'
},
replace: true,
template: [
'<div class="sg-event">',
' <span ng-if="!block.component.c_isallday">{{ block.starthour }} - </span>',
' {{ block.component.c_title }}',
' <span class="icons">',
' <i ng-if="block.component.c_nextalarm" class="md-icon-alarm"></i>',
' <i ng-if="block.component.c_classification == 1" class="md-icon-visibility-off"></i>',
' <i ng-if="block.component.c_classification == 2" class="md-icon-vpn-key"></i>',
' </span>',
'<div class="sg-event sg-draggable" ng-click="clickBlock({clickEvent: $event, clickComponent: block.component})">',
' <span ng-if="!block.component.c_isallday">{{ block.starthour }} - </span>',
' {{ block.component.c_title }}',
' <span class="icons">',
' <i ng-if="block.component.c_nextalarm" class="md-icon-alarm"></i>',
' <i ng-if="block.component.c_classification == 1" class="md-icon-visibility-off"></i>',
' <i ng-if="block.component.c_classification == 2" class="md-icon-vpn-key"></i>',
' </span>',
' <div class="leftDragGrip"></div>',
' <div class="rightDragGrip"></div>',
' </div>',
'</div>'
].join(''),
link: link
File diff suppressed because it is too large. Load diff
+33
View File
@@ -0,0 +1,33 @@
/*
AngularJS v1.3.17
(c) 2010-2014 Google, Inc. http://angularjs.org
License: MIT
*/
(function(N,f,W){'use strict';f.module("ngAnimate",["ng"]).directive("ngAnimateChildren",function(){return function(X,r,g){g=g.ngAnimateChildren;f.isString(g)&&0===g.length?r.data("$$ngAnimateChildren",!0):X.$watch(g,function(f){r.data("$$ngAnimateChildren",!!f)})}}).factory("$$animateReflow",["$$rAF","$document",function(f,r){var g=r[0].body;return function(r){return f(function(){r(g.offsetWidth)})}}]).config(["$provide","$animateProvider",function(X,r){function g(f){for(var n=0;n<f.length;n++){var g=
f[n];if(1==g.nodeType)return g}}function ba(f,n){return g(f)==g(n)}var t=f.noop,n=f.forEach,da=r.$$selectors,aa=f.isArray,ea=f.isString,ga=f.isObject,w={running:!0},u;X.decorator("$animate",["$delegate","$$q","$injector","$sniffer","$rootElement","$$asyncCallback","$rootScope","$document","$templateRequest","$$jqLite",function(O,N,M,Y,y,H,P,W,Z,Q){function R(a,c){var b=a.data("$$ngAnimateState")||{};c&&(b.running=!0,b.structural=!0,a.data("$$ngAnimateState",b));return b.disabled||b.running&&b.structural}
function D(a){var c,b=N.defer();b.promise.$$cancelFn=function(){c&&c()};P.$$postDigest(function(){c=a(function(){b.resolve()})});return b.promise}function I(a){if(ga(a))return a.tempClasses&&ea(a.tempClasses)&&(a.tempClasses=a.tempClasses.split(/\s+/)),a}function S(a,c,b){b=b||{};var d={};n(b,function(e,a){n(a.split(" "),function(a){d[a]=e})});var h=Object.create(null);n((a.attr("class")||"").split(/\s+/),function(e){h[e]=!0});var f=[],l=[];n(c&&c.classes||[],function(e,a){var b=h[a],c=d[a]||{};!1===
e?(b||"addClass"==c.event)&&l.push(a):!0===e&&(b&&"removeClass"!=c.event||f.push(a))});return 0<f.length+l.length&&[f.join(" "),l.join(" ")]}function T(a){if(a){var c=[],b={};a=a.substr(1).split(".");(Y.transitions||Y.animations)&&c.push(M.get(da[""]));for(var d=0;d<a.length;d++){var f=a[d],k=da[f];k&&!b[f]&&(c.push(M.get(k)),b[f]=!0)}return c}}function U(a,c,b,d){function h(e,a){var b=e[a],c=e["before"+a.charAt(0).toUpperCase()+a.substr(1)];if(b||c)return"leave"==a&&(c=b,b=null),u.push({event:a,
fn:b}),J.push({event:a,fn:c}),!0}function k(c,l,x){var E=[];n(c,function(a){a.fn&&E.push(a)});var m=0;n(E,function(c,f){var p=function(){a:{if(l){(l[f]||t)();if(++m<E.length)break a;l=null}x()}};switch(c.event){case "setClass":l.push(c.fn(a,e,A,p,d));break;case "animate":l.push(c.fn(a,b,d.from,d.to,p));break;case "addClass":l.push(c.fn(a,e||b,p,d));break;case "removeClass":l.push(c.fn(a,A||b,p,d));break;default:l.push(c.fn(a,p,d))}});l&&0===l.length&&x()}var l=a[0];if(l){d&&(d.to=d.to||{},d.from=
d.from||{});var e,A;aa(b)&&(e=b[0],A=b[1],e?A?b=e+" "+A:(b=e,c="addClass"):(b=A,c="removeClass"));var x="setClass"==c,E=x||"addClass"==c||"removeClass"==c||"animate"==c,p=a.attr("class")+" "+b;if(B(p)){var ca=t,m=[],J=[],g=t,s=[],u=[],p=(" "+p).replace(/\s+/g,".");n(T(p),function(a){!h(a,c)&&x&&(h(a,"addClass"),h(a,"removeClass"))});return{node:l,event:c,className:b,isClassBased:E,isSetClassOperation:x,applyStyles:function(){d&&a.css(f.extend(d.from||{},d.to||{}))},before:function(a){ca=a;k(J,m,function(){ca=
t;a()})},after:function(a){g=a;k(u,s,function(){g=t;a()})},cancel:function(){m&&(n(m,function(a){(a||t)(!0)}),ca(!0));s&&(n(s,function(a){(a||t)(!0)}),g(!0))}}}}}function G(a,c,b,d,h,k,l,e){function A(e){var l="$animate:"+e;J&&J[l]&&0<J[l].length&&H(function(){b.triggerHandler(l,{event:a,className:c})})}function x(){A("before")}function E(){A("after")}function p(){p.hasBeenRun||(p.hasBeenRun=!0,k())}function g(){if(!g.hasBeenRun){m&&m.applyStyles();g.hasBeenRun=!0;l&&l.tempClasses&&n(l.tempClasses,
function(a){u.removeClass(b,a)});var x=b.data("$$ngAnimateState");x&&(m&&m.isClassBased?C(b,c):(H(function(){var e=b.data("$$ngAnimateState")||{};fa==e.index&&C(b,c,a)}),b.data("$$ngAnimateState",x)));A("close");e()}}var m=U(b,a,c,l);if(!m)return p(),x(),E(),g(),t;a=m.event;c=m.className;var J=f.element._data(m.node),J=J&&J.events;d||(d=h?h.parent():b.parent());if(z(b,d))return p(),x(),E(),g(),t;d=b.data("$$ngAnimateState")||{};var L=d.active||{},s=d.totalActive||0,q=d.last;h=!1;if(0<s){s=[];if(m.isClassBased)"setClass"==
q.event?(s.push(q),C(b,c)):L[c]&&(v=L[c],v.event==a?h=!0:(s.push(v),C(b,c)));else if("leave"==a&&L["ng-leave"])h=!0;else{for(var v in L)s.push(L[v]);d={};C(b,!0)}0<s.length&&n(s,function(a){a.cancel()})}!m.isClassBased||m.isSetClassOperation||"animate"==a||h||(h="addClass"==a==b.hasClass(c));if(h)return p(),x(),E(),A("close"),e(),t;L=d.active||{};s=d.totalActive||0;if("leave"==a)b.one("$destroy",function(a){a=f.element(this);var e=a.data("$$ngAnimateState");e&&(e=e.active["ng-leave"])&&(e.cancel(),
C(a,"ng-leave"))});u.addClass(b,"ng-animate");l&&l.tempClasses&&n(l.tempClasses,function(a){u.addClass(b,a)});var fa=K++;s++;L[c]=m;b.data("$$ngAnimateState",{last:m,active:L,index:fa,totalActive:s});x();m.before(function(e){var l=b.data("$$ngAnimateState");e=e||!l||!l.active[c]||m.isClassBased&&l.active[c].event!=a;p();!0===e?g():(E(),m.after(g))});return m.cancel}function q(a){if(a=g(a))a=f.isFunction(a.getElementsByClassName)?a.getElementsByClassName("ng-animate"):a.querySelectorAll(".ng-animate"),
n(a,function(a){a=f.element(a);(a=a.data("$$ngAnimateState"))&&a.active&&n(a.active,function(a){a.cancel()})})}function C(a,c){if(ba(a,y))w.disabled||(w.running=!1,w.structural=!1);else if(c){var b=a.data("$$ngAnimateState")||{},d=!0===c;!d&&b.active&&b.active[c]&&(b.totalActive--,delete b.active[c]);if(d||!b.totalActive)u.removeClass(a,"ng-animate"),a.removeData("$$ngAnimateState")}}function z(a,c){if(w.disabled)return!0;if(ba(a,y))return w.running;var b,d,g;do{if(0===c.length)break;var k=ba(c,y),
l=k?w:c.data("$$ngAnimateState")||{};if(l.disabled)return!0;k&&(g=!0);!1!==b&&(k=c.data("$$ngAnimateChildren"),f.isDefined(k)&&(b=k));d=d||l.running||l.last&&!l.last.isClassBased}while(c=c.parent());return!g||!b&&d}u=Q;y.data("$$ngAnimateState",w);var $=P.$watch(function(){return Z.totalPendingRequests},function(a,c){0===a&&($(),P.$$postDigest(function(){P.$$postDigest(function(){w.running=!1})}))}),K=0,V=r.classNameFilter(),B=V?function(a){return V.test(a)}:function(){return!0};return{animate:function(a,
c,b,d,h){d=d||"ng-inline-animate";h=I(h)||{};h.from=b?c:null;h.to=b?b:c;return D(function(b){return G("animate",d,f.element(g(a)),null,null,t,h,b)})},enter:function(a,c,b,d){d=I(d);a=f.element(a);c=c&&f.element(c);b=b&&f.element(b);R(a,!0);O.enter(a,c,b);return D(function(h){return G("enter","ng-enter",f.element(g(a)),c,b,t,d,h)})},leave:function(a,c){c=I(c);a=f.element(a);q(a);R(a,!0);return D(function(b){return G("leave","ng-leave",f.element(g(a)),null,null,function(){O.leave(a)},c,b)})},move:function(a,
c,b,d){d=I(d);a=f.element(a);c=c&&f.element(c);b=b&&f.element(b);q(a);R(a,!0);O.move(a,c,b);return D(function(h){return G("move","ng-move",f.element(g(a)),c,b,t,d,h)})},addClass:function(a,c,b){return this.setClass(a,c,[],b)},removeClass:function(a,c,b){return this.setClass(a,[],c,b)},setClass:function(a,c,b,d){d=I(d);a=f.element(a);a=f.element(g(a));if(R(a))return O.$$setClassImmediately(a,c,b,d);var h,k=a.data("$$animateClasses"),l=!!k;k||(k={classes:{}});h=k.classes;c=aa(c)?c:c.split(" ");n(c,
function(a){a&&a.length&&(h[a]=!0)});b=aa(b)?b:b.split(" ");n(b,function(a){a&&a.length&&(h[a]=!1)});if(l)return d&&k.options&&(k.options=f.extend(k.options||{},d)),k.promise;a.data("$$animateClasses",k={classes:h,options:d});return k.promise=D(function(e){var l=a.parent(),b=g(a),c=b.parentNode;if(!c||c.$$NG_REMOVED||b.$$NG_REMOVED)e();else{b=a.data("$$animateClasses");a.removeData("$$animateClasses");var c=a.data("$$ngAnimateState")||{},d=S(a,b,c.active);return d?G("setClass",d,a,l,null,function(){d[0]&&
O.$$addClassImmediately(a,d[0]);d[1]&&O.$$removeClassImmediately(a,d[1])},b.options,e):e()}})},cancel:function(a){a.$$cancelFn()},enabled:function(a,c){switch(arguments.length){case 2:if(a)C(c);else{var b=c.data("$$ngAnimateState")||{};b.disabled=!0;c.data("$$ngAnimateState",b)}break;case 1:w.disabled=!a;break;default:a=!w.disabled}return!!a}}}]);r.register("",["$window","$sniffer","$timeout","$$animateReflow",function(r,w,M,Y){function y(){b||(b=Y(function(){c=[];b=null;B={}}))}function H(a,e){b&&
b();c.push(e);b=Y(function(){n(c,function(a){a()});c=[];b=null;B={}})}function P(a,e){var b=g(a);a=f.element(b);k.push(a);b=Date.now()+e;b<=h||(M.cancel(d),h=b,d=M(function(){X(k);k=[]},e,!1))}function X(a){n(a,function(a){(a=a.data("$$ngAnimateCSS3Data"))&&n(a.closeAnimationFns,function(a){a()})})}function Z(a,e){var b=e?B[e]:null;if(!b){var c=0,d=0,f=0,g=0;n(a,function(a){if(1==a.nodeType){a=r.getComputedStyle(a)||{};c=Math.max(Q(a[z+"Duration"]),c);d=Math.max(Q(a[z+"Delay"]),d);g=Math.max(Q(a[K+
"Delay"]),g);var e=Q(a[K+"Duration"]);0<e&&(e*=parseInt(a[K+"IterationCount"],10)||1);f=Math.max(e,f)}});b={total:0,transitionDelay:d,transitionDuration:c,animationDelay:g,animationDuration:f};e&&(B[e]=b)}return b}function Q(a){var e=0;a=ea(a)?a.split(/\s*,\s*/):[];n(a,function(a){e=Math.max(parseFloat(a)||0,e)});return e}function R(b,e,c,d){b=0<=["ng-enter","ng-leave","ng-move"].indexOf(c);var f,p=e.parent(),h=p.data("$$ngAnimateKey");h||(p.data("$$ngAnimateKey",++a),h=a);f=h+"-"+g(e).getAttribute("class");
var p=f+" "+c,h=B[p]?++B[p].total:0,m={};if(0<h){var n=c+"-stagger",m=f+" "+n;(f=!B[m])&&u.addClass(e,n);m=Z(e,m);f&&u.removeClass(e,n)}u.addClass(e,c);var n=e.data("$$ngAnimateCSS3Data")||{},k=Z(e,p);f=k.transitionDuration;k=k.animationDuration;if(b&&0===f&&0===k)return u.removeClass(e,c),!1;c=d||b&&0<f;b=0<k&&0<m.animationDelay&&0===m.animationDuration;e.data("$$ngAnimateCSS3Data",{stagger:m,cacheKey:p,running:n.running||0,itemIndex:h,blockTransition:c,closeAnimationFns:n.closeAnimationFns||[]});
p=g(e);c&&(I(p,!0),d&&e.css(d));b&&(p.style[K+"PlayState"]="paused");return!0}function D(a,e,b,c,d){function f(){e.off(D,h);u.removeClass(e,k);u.removeClass(e,t);z&&M.cancel(z);G(e,b);var a=g(e),c;for(c in s)a.style.removeProperty(s[c])}function h(a){a.stopPropagation();var b=a.originalEvent||a;a=b.$manualTimeStamp||b.timeStamp||Date.now();b=parseFloat(b.elapsedTime.toFixed(3));Math.max(a-H,0)>=B&&b>=y&&c()}var m=g(e);a=e.data("$$ngAnimateCSS3Data");if(-1!=m.getAttribute("class").indexOf(b)&&a){var k=
"",t="";n(b.split(" "),function(a,b){var e=(0<b?" ":"")+a;k+=e+"-active";t+=e+"-pending"});var s=[],q=a.itemIndex,v=a.stagger,r=0;if(0<q){r=0;0<v.transitionDelay&&0===v.transitionDuration&&(r=v.transitionDelay*q);var w=0;0<v.animationDelay&&0===v.animationDuration&&(w=v.animationDelay*q,s.push(C+"animation-play-state"));r=Math.round(100*Math.max(r,w))/100}r||(u.addClass(e,k),a.blockTransition&&I(m,!1));var F=Z(e,a.cacheKey+" "+k),y=Math.max(F.transitionDuration,F.animationDuration);if(0===y)u.removeClass(e,
k),G(e,b),c();else{!r&&d&&0<Object.keys(d).length&&(F.transitionDuration||(e.css("transition",F.animationDuration+"s linear all"),s.push("transition")),e.css(d));var q=Math.max(F.transitionDelay,F.animationDelay),B=1E3*q;0<s.length&&(v=m.getAttribute("style")||"",";"!==v.charAt(v.length-1)&&(v+=";"),m.setAttribute("style",v+" "));var H=Date.now(),D=V+" "+$,q=1E3*(r+1.5*(q+y)),z;0<r&&(u.addClass(e,t),z=M(function(){z=null;0<F.transitionDuration&&I(m,!1);0<F.animationDuration&&(m.style[K+"PlayState"]=
"");u.addClass(e,k);u.removeClass(e,t);d&&(0===F.transitionDuration&&e.css("transition",F.animationDuration+"s linear all"),e.css(d),s.push("transition"))},1E3*r,!1));e.on(D,h);a.closeAnimationFns.push(function(){f();c()});a.running++;P(e,q);return f}}else c()}function I(a,b){a.style[z+"Property"]=b?"none":""}function S(a,b,c,d){if(R(a,b,c,d))return function(a){a&&G(b,c)}}function T(a,b,c,d,f){if(b.data("$$ngAnimateCSS3Data"))return D(a,b,c,d,f);G(b,c);d()}function U(a,b,c,d,f){var g=S(a,b,c,f.from);
if(g){var h=g;H(b,function(){h=T(a,b,c,d,f.to)});return function(a){(h||t)(a)}}y();d()}function G(a,b){u.removeClass(a,b);var c=a.data("$$ngAnimateCSS3Data");c&&(c.running&&c.running--,c.running&&0!==c.running||a.removeData("$$ngAnimateCSS3Data"))}function q(a,b){var c="";a=aa(a)?a:a.split(/\s+/);n(a,function(a,d){a&&0<a.length&&(c+=(0<d?" ":"")+a+b)});return c}var C="",z,$,K,V;N.ontransitionend===W&&N.onwebkittransitionend!==W?(C="-webkit-",z="WebkitTransition",$="webkitTransitionEnd transitionend"):
(z="transition",$="transitionend");N.onanimationend===W&&N.onwebkitanimationend!==W?(C="-webkit-",K="WebkitAnimation",V="webkitAnimationEnd animationend"):(K="animation",V="animationend");var B={},a=0,c=[],b,d=null,h=0,k=[];return{animate:function(a,b,c,d,f,g){g=g||{};g.from=c;g.to=d;return U("animate",a,b,f,g)},enter:function(a,b,c){c=c||{};return U("enter",a,"ng-enter",b,c)},leave:function(a,b,c){c=c||{};return U("leave",a,"ng-leave",b,c)},move:function(a,b,c){c=c||{};return U("move",a,"ng-move",
b,c)},beforeSetClass:function(a,b,c,d,f){f=f||{};b=q(c,"-remove")+" "+q(b,"-add");if(f=S("setClass",a,b,f.from))return H(a,d),f;y();d()},beforeAddClass:function(a,b,c,d){d=d||{};if(b=S("addClass",a,q(b,"-add"),d.from))return H(a,c),b;y();c()},beforeRemoveClass:function(a,b,c,d){d=d||{};if(b=S("removeClass",a,q(b,"-remove"),d.from))return H(a,c),b;y();c()},setClass:function(a,b,c,d,f){f=f||{};c=q(c,"-remove");b=q(b,"-add");return T("setClass",a,c+" "+b,d,f.to)},addClass:function(a,b,c,d){d=d||{};return T("addClass",
a,q(b,"-add"),c,d.to)},removeClass:function(a,b,c,d){d=d||{};return T("removeClass",a,q(b,"-remove"),c,d.to)}}}])}])})(window,window.angular);
//# sourceMappingURL=angular-animate.min.js.map
@@ -0,0 +1,8 @@
{
"version":3,
"file":"angular-animate.min.js",
"lineCount":32,
"mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAwYtCD,CAAAE,OAAA,CAAe,WAAf,CAA4B,CAAC,IAAD,CAA5B,CAAAC,UAAA,CAgBa,mBAhBb,CAgBkC,QAAQ,EAAG,CAEzC,MAAO,SAAQ,CAACC,CAAD,CAAQC,CAAR,CAAiBC,CAAjB,CAAwB,CACjCC,CAAAA,CAAMD,CAAAE,kBACNR,EAAAS,SAAA,CAAiBF,CAAjB,CAAJ,EAA4C,CAA5C,GAA6BA,CAAAG,OAA7B,CACEL,CAAAM,KAAA,CAJsBC,qBAItB,CAAkC,CAAA,CAAlC,CADF,CAGER,CAAAS,OAAA,CAAaN,CAAb,CAAkB,QAAQ,CAACO,CAAD,CAAQ,CAChCT,CAAAM,KAAA,CAPoBC,qBAOpB,CAAkC,CAAEE,CAAAA,CAApC,CADgC,CAAlC,CALmC,CAFE,CAhB7C,CAAAC,QAAA,CAkCW,iBAlCX,CAkC8B,CAAC,OAAD,CAAU,WAAV,CAAuB,QAAQ,CAACC,CAAD,CAAQC,CAAR,CAAmB,CAC5E,IAAIC,EAAMD,CAAA,CAAU,CAAV,CAAAE,KACV,OAAO,SAAQ,CAACC,CAAD,CAAK,CAElB,MAAOJ,EAAA,CAAM,QAAQ,EAAG,CAStBI,CAAA,CAAGF,CAAAG,YAAH,CATsB,CAAjB,CAFW,CAFwD,CAAlD,CAlC9B,CAAAC,OAAA,CAoDU,CAAC,UAAD,CAAa,kBAAb,CAAiC,QAAQ,CAACC,CAAD,CAAWC,CAAX,CAA6B,CAc5EC,QAASA,EAAkB,CAACpB,CAAD,CAAU,CACnC,IAAS,IAAAqB,EAAI,CAAb,CAAgBA,CAAhB,CAAoBrB,CAAAK,OAApB,CAAoCgB,CAAA,EAApC,CAAyC,CACvC,IAAIC;AAAMtB,CAAA,CAAQqB,CAAR,CACV,IATeE,CASf,EAAID,CAAAE,SAAJ,CACE,MAAOF,EAH8B,CADN,CAiBrCG,QAASA,GAAiB,CAACC,CAAD,CAAOC,CAAP,CAAa,CACrC,MAAOP,EAAA,CAAmBM,CAAnB,CAAP,EAAmCN,CAAA,CAAmBO,CAAnB,CADE,CA9BvC,IAAIC,EAAOjC,CAAAiC,KAAX,CACIC,EAAUlC,CAAAkC,QADd,CAEIC,GAAYX,CAAAY,YAFhB,CAGIC,GAAUrC,CAAAqC,QAHd,CAII5B,GAAWT,CAAAS,SAJf,CAKI6B,GAAWtC,CAAAsC,SALf,CAWIC,EAAmB,CAACC,QAAS,CAAA,CAAV,CAXvB,CAiCIC,CACJlB,EAAAmB,UAAA,CAAmB,UAAnB,CACI,CAAC,WAAD,CAAc,KAAd,CAAqB,WAArB,CAAkC,UAAlC,CAA8C,cAA9C,CAA8D,iBAA9D,CAAiF,YAAjF,CAA+F,WAA/F,CAA4G,kBAA5G,CAAgI,UAAhI,CACP,QAAQ,CAACC,CAAD,CAAcC,CAAd,CAAqBC,CAArB,CAAkCC,CAAlC,CAA8CC,CAA9C,CAA8DC,CAA9D,CAAiFC,CAAjF,CAA+FhC,CAA/F,CAA4GiC,CAA5G,CAAgIC,CAAhI,CAA2I,CAsC9IC,QAASA,EAA2B,CAAC/C,CAAD,CAAUgD,CAAV,CAAkB,CACpD,IAAI1C,EAAON,CAAAM,KAAA,CAnEQ2C,kBAmER,CAAP3C,EAAyC,EACzC0C,EAAJ,GACE1C,CAAA6B,QAEA,CAFe,CAAA,CAEf,CADA7B,CAAA4C,WACA,CADkB,CAAA,CAClB,CAAAlD,CAAAM,KAAA,CAvEiB2C,kBAuEjB,CAA+B3C,CAA/B,CAHF,CAKA,OAAOA,EAAA6C,SAAP,EAAyB7C,CAAA6B,QAAzB,EAAyC7B,CAAA4C,WAPW,CAtCwF;AAgD9IE,QAASA,EAAsB,CAACrC,CAAD,CAAK,CAAA,IAC9BsC,CAD8B,CACpBC,EAAQf,CAAAe,MAAA,EACtBA,EAAAC,QAAAC,WAAA,CAA2BC,QAAQ,EAAG,CACpCJ,CAAA,EAAYA,CAAA,EADwB,CAGtCT,EAAAc,aAAA,CAAwB,QAAQ,EAAG,CACjCL,CAAA,CAAWtC,CAAA,CAAG,QAAQ,EAAG,CACvBuC,CAAAK,QAAA,EADuB,CAAd,CADsB,CAAnC,CAKA,OAAOL,EAAAC,QAV2B,CAapCK,QAASA,EAAmB,CAACC,CAAD,CAAU,CAIpC,GAAI5B,EAAA,CAAS4B,CAAT,CAAJ,CAIE,MAHIA,EAAAC,YAGGD,EAHoBzD,EAAA,CAASyD,CAAAC,YAAT,CAGpBD,GAFLA,CAAAC,YAEKD,CAFiBA,CAAAC,YAAAC,MAAA,CAA0B,KAA1B,CAEjBF,EAAAA,CAR2B,CAYtCG,QAASA,EAAqB,CAAChE,CAAD,CAAUiE,CAAV,CAAiBC,CAAjB,CAAoC,CAChEA,CAAA,CAAoBA,CAApB,EAAyC,EAEzC,KAAIC,EAAS,EACbtC,EAAA,CAAQqC,CAAR,CAA2B,QAAQ,CAAC5D,CAAD,CAAO8D,CAAP,CAAiB,CAClDvC,CAAA,CAAQuC,CAAAL,MAAA,CAAe,GAAf,CAAR,CAA6B,QAAQ,CAACM,CAAD,CAAI,CACvCF,CAAA,CAAOE,CAAP,CAAA,CAAU/D,CAD6B,CAAzC,CADkD,CAApD,CAMA,KAAIgE,EAAaC,MAAAC,OAAA,CAAc,IAAd,CACjB3C,EAAA,CAAQkC,CAAC/D,CAAAyE,KAAA,CAAa,OAAb,CAADV,EAA0B,EAA1BA,OAAA,CAAoC,KAApC,CAAR,CAAoD,QAAQ,CAACW,CAAD,CAAY,CACtEJ,CAAA,CAAWI,CAAX,CAAA,CAAwB,CAAA,CAD8C,CAAxE,CAXgE,KAe5DC,EAAQ,EAfoD,CAehDC,EAAW,EAC3B/C,EAAA,CAASoC,CAAT,EAAkBA,CAAAY,QAAlB,EAAoC,EAApC,CAAwC,QAAQ,CAACC,CAAD,CAASJ,CAAT,CAAoB,CAClE,IAAIK,EAAWT,CAAA,CAAWI,CAAX,CAAf,CACIM,EAAoBb,CAAA,CAAOO,CAAP,CAApBM,EAAyC,EAU9B,EAAA,CAAf;AAAIF,CAAJ,EAEMC,CAFN,EAE6C,UAF7C,EAEkBC,CAAAC,MAFlB,GAGIL,CAAAM,KAAA,CAAcR,CAAd,CAHJ,CAKsB,CAAA,CALtB,GAKWI,CALX,GAOOC,CAPP,EAO8C,aAP9C,EAOmBC,CAAAC,MAPnB,EAQIN,CAAAO,KAAA,CAAWR,CAAX,CARJ,CAZkE,CAApE,CAyBA,OAA0C,EAA1C,CAAQC,CAAAtE,OAAR,CAAuBuE,CAAAvE,OAAvB,EAA+C,CAACsE,CAAAQ,KAAA,CAAW,GAAX,CAAD,CAAkBP,CAAAO,KAAA,CAAc,GAAd,CAAlB,CAzCiB,CA4ClEhB,QAASA,EAAM,CAACiB,CAAD,CAAO,CACpB,GAAIA,CAAJ,CAAU,CAAA,IACJC,EAAU,EADN,CAEJC,EAAU,EACVT,EAAAA,CAAUO,CAAAG,OAAA,CAAY,CAAZ,CAAAxB,MAAA,CAAqB,GAArB,CAUd,EAAItB,CAAA+C,YAAJ,EAA4B/C,CAAAgD,WAA5B,GACEJ,CAAAH,KAAA,CAAa1C,CAAAkD,IAAA,CAAc5D,EAAA,CAAU,EAAV,CAAd,CAAb,CAGF,KAAS,IAAAT,EAAE,CAAX,CAAcA,CAAd,CAAkBwD,CAAAxE,OAAlB,CAAkCgB,CAAA,EAAlC,CAAuC,CAAA,IACjCsE,EAAQd,CAAA,CAAQxD,CAAR,CADyB,CAEjCuE,EAAsB9D,EAAA,CAAU6D,CAAV,CACtBC,EAAJ,EAA4B,CAAAN,CAAA,CAAQK,CAAR,CAA5B,GACEN,CAAAH,KAAA,CAAa1C,CAAAkD,IAAA,CAAcE,CAAd,CAAb,CACA,CAAAN,CAAA,CAAQK,CAAR,CAAA,CAAiB,CAAA,CAFnB,CAHqC,CAQvC,MAAON,EAzBC,CADU,CA8BtBQ,QAASA,EAAe,CAAC7F,CAAD,CAAU8F,CAAV,CAA0BpB,CAA1B,CAAqCb,CAArC,CAA8C,CAyDpEkC,QAASA,EAAiB,CAACC,CAAD,CAAmBf,CAAnB,CAA0B,CAClD,IAAIgB,EAAUD,CAAA,CAAiBf,CAAjB,CAAd,CACIiB,EAAWF,CAAA,CAAiB,QAAjB,CAA4Bf,CAAAkB,OAAA,CAAa,CAAb,CAAAC,YAAA,EAA5B,CAA4DnB,CAAAM,OAAA,CAAa,CAAb,CAA5D,CACf,IAAIU,CAAJ,EAAeC,CAAf,CAYE,MAXa,OAWN,EAXHjB,CAWG,GAVLiB,CAEA,CAFWD,CAEX,CAAAA,CAAA,CAAU,IAQL,EANPI,CAAAnB,KAAA,CAAW,CACTD,MAAOA,CADE;AACKlE,GAAIkF,CADT,CAAX,CAMO,CAHPK,CAAApB,KAAA,CAAY,CACVD,MAAOA,CADG,CACIlE,GAAImF,CADR,CAAZ,CAGO,CAAA,CAAA,CAfyC,CAmBpDK,QAASA,EAAG,CAACC,CAAD,CAAMC,CAAN,CAAqBC,CAArB,CAAoC,CAC9C,IAAIjB,EAAa,EACjB5D,EAAA,CAAQ2E,CAAR,CAAa,QAAQ,CAACG,CAAD,CAAY,CAC/BA,CAAA5F,GAAA,EAAgB0E,CAAAP,KAAA,CAAgByB,CAAhB,CADe,CAAjC,CAIA,KAAIC,EAAQ,CAaZ/E,EAAA,CAAQ4D,CAAR,CAAoB,QAAQ,CAACkB,CAAD,CAAYE,CAAZ,CAAmB,CAC7C,IAAIC,EAAWA,QAAQ,EAAG,CAbW,CAAA,CAAA,Line truncated
"sources":["angular-animate.js"],
"names":["window","angular","undefined","module","directive","scope","element","attrs","val","ngAnimateChildren","isString","length","data","NG_ANIMATE_CHILDREN","$watch","value","factory","$$rAF","$document","bod","body","fn","offsetWidth","config","$provide","$animateProvider","extractElementNode","i","elm","ELEMENT_NODE","nodeType","isMatchingElement","elm1","elm2","noop","forEach","selectors","$$selectors","isArray","isObject","rootAnimateState","running","$$jqLite","decorator","$delegate","$$q","$injector","$sniffer","$rootElement","$$asyncCallback","$rootScope","$templateRequest","$$$jqLite","classBasedAnimationsBlocked","setter","NG_ANIMATE_STATE","structural","disabled","runAnimationPostDigest","cancelFn","defer","promise","$$cancelFn","defer.promise.$$cancelFn","$$postDigest","resolve","parseAnimateOptions","options","tempClasses","split","resolveElementClasses","cache","runningAnimations","lookup","selector","s","hasClasses","Object","create","attr","className","toAdd","toRemove","classes","status","hasClass","matchingAnimation","event","push","join","name","matches","flagMap","substr","transitions","animations","get","klass","selectorFactoryName","animationRunner","animationEvent","registerAnimation","animationFactory","afterFn","beforeFn","charAt","toUpperCase","after","before","run","fns","cancellations","allCompleteFn","animation","count","index","progress","classNameAdd","classNameRemove","from","to","node","isSetClassOperation","isClassBased","currentClassName","isAnimatableClassName","beforeComplete","beforeCancel","afterComplete","afterCancel","animationLookup","replace","created","applyStyles","css","extend","cancel","performAnimation","parentElement","afterElement","domOperation","doneCallback","fireDOMCallback","animationPhase","eventName","elementEvents","triggerHandler","fireBeforeCallbackAsync","fireAfterCallbackAsync","fireDOMOperation","hasBeenRun","closeAnimation","runner","removeClass","cleanup","localAnimationCount","_data","events","parent","animationsDisabled","ngAnimateState","active","totalActiveAnimations","totalActive","lastAnimation","last","skipAnimation","animationsToCancel","current","operation","one","e","state","activeLeaveAnimation","addClass","NG_ANIMATE_CLASS_NAME","globalAnimationCounter","cancelled","cancelChildAnimations","nodes","isFunction","getElementsByClassName","querySelectorAll","removeAnimations","removeData","allowChildAnimations","parentRunningAnimation","hasParent","isRoot","animateChildrenFlag","isDefined","deregisterWatch","totalPendingRequests","oldVal","classNameFilter","test","animate","done","enter","leave","move","setClass","add","remove","$$setClassImmediately","STORAGE_KEY","hasCache","c","elementNode","parentNode","$$addClassImmediately","$$removeClassImmediately","enabled","arguments","register","$window","$timeout","$$animateReflow","clearCacheAfterReflow","cancelAnimationReflow","animationReflowQueue","lookupCache","afterReflow","callback","animationCloseHandler","totalTime","animationElementQueue","futureTimestamp","Date","now","closingTimestamp","closingTimer","closeAllAnimations","elements","elementData","NG_ANIMATE_CSS_DATA_KEY","closeAnimationFns","getElementAnimationDetails","cacheKey","transitionDuration","transitionDelay","animationDuration","animationDelay","elementStyles","getComputedStyle","Math","max","parseMaxTime","transitionDurationStyle","TRANSITION_PROP","DURATION_KEY","transitionDelayStyle","DELAY_KEY","ANIMATION_PROP","aDuration","parseInt","ANIMATION_ITERATION_COUNT_KEY","total","str","maxValue","values","parseFloat","animateSetup","styles","indexOf","parentID","NG_ANIMATE_PARENT_KEY","parentCounter","getAttribute","eventCacheKey","itemIndex","stagger","staggerClassName","staggerCacheKey","applyClasses","formerData","timings","blockTransition","blockAnimation","blockTransitions","style","ANIMATION_PLAYSTATE_KEY","animateRun","activeAnimationComplete","onEnd","off","css3AnimationEvents","onAnimationProgress","activeClassName","pendingClassName","staggerTimeout","animateClose","appliedStyles","removeProperty","stopPropagation","ev","originalEvent","timeStamp","$manualTimeStamp","elapsedTime","toFixed","ELAPSED_TIME_MAX_DECIMAL_PLACES","startTime","maxDelayTime","maxDuration","prefix","staggerTime","transitionStaggerDelay","animationStaggerDelay","CSS_PREFIX","round","keys","maxDelay","ONE_SECOND","oldStyle","setAttribute","ANIMATIONEND_EVENT","TRANSITIONEND_EVENT","CLOSING_TIME_BUFFER","on","bool","PROPERTY_KEY","animateBefore","animateAfter","afterAnimationComplete","animationComplete","preReflowCancellation","suffixClasses","suffix","ontransitionend","onwebkittransitionend","onanimationend","onwebkitanimationend","animationCompleted","beforeSetClass","cancellationMethod","beforeAddClass","beforeRemoveClass"]
}
+393
View File
@@ -0,0 +1,393 @@
/**
* @license AngularJS v1.4.3
* (c) 2010-2015 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {'use strict';
/**
* @ngdoc module
* @name ngAria
* @description
*
* The `ngAria` module provides support for common
* [<abbr title="Accessible Rich Internet Applications">ARIA</abbr>](http://www.w3.org/TR/wai-aria/)
* attributes that convey state or semantic information about the application for users
* of assistive technologies, such as screen readers.
*
* <div doc-module-components="ngAria"></div>
*
* ## Usage
*
* For ngAria to do its magic, simply include the module `ngAria` as a dependency. The following
* directives are supported:
* `ngModel`, `ngDisabled`, `ngShow`, `ngHide`, `ngClick`, `ngDblClick`, and `ngMessages`.
*
* Below is a more detailed breakdown of the attributes handled by ngAria:
*
* | Directive | Supported Attributes |
* |---------------------------------------------|----------------------------------------------------------------------------------------|
* | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
* | {@link ng.directive:ngShow ngShow} | aria-hidden |
* | {@link ng.directive:ngHide ngHide} | aria-hidden |
* | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
* | {@link module:ngMessages ngMessages} | aria-live |
* | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles |
* | {@link ng.directive:ngClick ngClick} | tabindex, keypress event, button role |
*
* Find out more information about each directive by reading the
* {@link guide/accessibility ngAria Developer Guide}.
*
* ##Example
* Using ngDisabled with ngAria:
* ```html
* <md-checkbox ng-disabled="disabled">
* ```
* Becomes:
* ```html
* <md-checkbox ng-disabled="disabled" aria-disabled="true">
* ```
*
* ##Disabling Attributes
* It's possible to disable individual attributes added by ngAria with the
* {@link ngAria.$ariaProvider#config config} method. For more details, see the
* {@link guide/accessibility Developer Guide}.
*/
/* global -ngAriaModule */
var ngAriaModule = angular.module('ngAria', ['ng']).
provider('$aria', $AriaProvider);
/**
* @ngdoc provider
* @name $ariaProvider
*
* @description
*
* Used for configuring the ARIA attributes injected and managed by ngAria.
*
* ```js
* angular.module('myApp', ['ngAria'], function config($ariaProvider) {
* $ariaProvider.config({
* ariaValue: true,
* tabindex: false
* });
* });
*```
*
* ## Dependencies
* Requires the {@link ngAria} module to be installed.
*
*/
function $AriaProvider() {
var config = {
ariaHidden: true,
ariaChecked: true,
ariaDisabled: true,
ariaRequired: true,
ariaInvalid: true,
ariaMultiline: true,
ariaValue: true,
tabindex: true,
bindKeypress: true,
bindRoleForClick: true
};
/**
* @ngdoc method
* @name $ariaProvider#config
*
* @param {object} config object to enable/disable specific ARIA attributes
*
* - **ariaHidden** – `{boolean}` – Enables/disables aria-hidden tags
* - **ariaChecked** – `{boolean}` – Enables/disables aria-checked tags
* - **ariaDisabled** – `{boolean}` – Enables/disables aria-disabled tags
* - **ariaRequired** – `{boolean}` – Enables/disables aria-required tags
* - **ariaInvalid** – `{boolean}` – Enables/disables aria-invalid tags
* - **ariaMultiline** – `{boolean}` – Enables/disables aria-multiline tags
* - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and aria-valuenow tags
* - **tabindex** – `{boolean}` – Enables/disables tabindex tags
* - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on `&lt;div&gt;` and
* `&lt;li&gt;` elements with ng-click
* - **bindRoleForClick** – `{boolean}` – Adds role=button to non-interactive elements like `div`
* using ng-click, making them more accessible to users of assistive technologies
*
* @description
* Enables/disables various ARIA attributes
*/
this.config = function(newConfig) {
config = angular.extend(config, newConfig);
};
function watchExpr(attrName, ariaAttr, negate) {
return function(scope, elem, attr) {
var ariaCamelName = attr.$normalize(ariaAttr);
if (config[ariaCamelName] && !attr[ariaCamelName]) {
scope.$watch(attr[attrName], function(boolVal) {
// ensure boolean value
boolVal = negate ? !boolVal : !!boolVal;
elem.attr(ariaAttr, boolVal);
});
}
};
}
/**
* @ngdoc service
* @name $aria
*
* @description
* @priority 200
*
* The $aria service contains helper methods for applying common
* [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives.
*
* ngAria injects common accessibility attributes that tell assistive technologies when HTML
* elements are enabled, selected, hidden, and more. To see how this is performed with ngAria,
* let's review a code snippet from ngAria itself:
*
*```js
* ngAriaModule.directive('ngDisabled', ['$aria', function($aria) {
* return $aria.$$watchExpr('ngDisabled', 'aria-disabled');
* }])
*```
* Shown above, the ngAria module creates a directive with the same signature as the
* traditional `ng-disabled` directive. But this ngAria version is dedicated to
* solely managing accessibility attributes. The internal `$aria` service is used to watch the
* boolean attribute `ngDisabled`. If it has not been explicitly set by the developer,
* `aria-disabled` is injected as an attribute with its value synchronized to the value in
* `ngDisabled`.
*
* Because ngAria hooks into the `ng-disabled` directive, developers do not have to do
* anything to enable this feature. The `aria-disabled` attribute is automatically managed
* simply as a silent side-effect of using `ng-disabled` with the ngAria module.
*
* The full list of directives that interface with ngAria:
* * **ngModel**
* * **ngShow**
* * **ngHide**
* * **ngClick**
* * **ngDblclick**
* * **ngMessages**
* * **ngDisabled**
*
* Read the {@link guide/accessibility ngAria Developer Guide} for a thorough explanation of each
* directive.
*
*
* ## Dependencies
* Requires the {@link ngAria} module to be installed.
*/
this.$get = function() {
return {
config: function(key) {
return config[key];
},
$$watchExpr: watchExpr
};
};
}
ngAriaModule.directive('ngShow', ['$aria', function($aria) {
return $aria.$$watchExpr('ngShow', 'aria-hidden', true);
}])
.directive('ngHide', ['$aria', function($aria) {
return $aria.$$watchExpr('ngHide', 'aria-hidden', false);
}])
.directive('ngModel', ['$aria', function($aria) {
function shouldAttachAttr(attr, normalizedAttr, elem) {
return $aria.config(normalizedAttr) && !elem.attr(attr);
}
function shouldAttachRole(role, elem) {
return !elem.attr('role') && (elem.attr('type') === role) && (elem[0].nodeName !== 'INPUT');
}
function getShape(attr, elem) {
var type = attr.type,
role = attr.role;
return ((type || role) === 'checkbox' || role === 'menuitemcheckbox') ? 'checkbox' :
((type || role) === 'radio' || role === 'menuitemradio') ? 'radio' :
(type === 'range' || role === 'progressbar' || role === 'slider') ? 'range' :
(type || role) === 'textbox' || elem[0].nodeName === 'TEXTAREA' ? 'multiline' : '';
}
return {
restrict: 'A',
require: '?ngModel',
priority: 200, //Make sure watches are fired after any other directives that affect the ngModel value
compile: function(elem, attr) {
var shape = getShape(attr, elem);
return {
pre: function(scope, elem, attr, ngModel) {
if (shape === 'checkbox' && attr.type !== 'checkbox') {
//Use the input[checkbox] $isEmpty implementation for elements with checkbox roles
ngModel.$isEmpty = function(value) {
return value === false;
};
}
},
post: function(scope, elem, attr, ngModel) {
var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem);
function ngAriaWatchModelValue() {
return ngModel.$modelValue;
}
function getRadioReaction() {
if (needsTabIndex) {
needsTabIndex = false;
return function ngAriaRadioReaction(newVal) {
var boolVal = (attr.value == ngModel.$viewValue);
elem.attr('aria-checked', boolVal);
elem.attr('tabindex', 0 - !boolVal);
};
} else {
return function ngAriaRadioReaction(newVal) {
elem.attr('aria-checked', (attr.value == ngModel.$viewValue));
};
}
}
function ngAriaCheckboxReaction() {
elem.attr('aria-checked', !ngModel.$isEmpty(ngModel.$viewValue));
}
switch (shape) {
case 'radio':
case 'checkbox':
if (shouldAttachRole(shape, elem)) {
elem.attr('role', shape);
}
if (shouldAttachAttr('aria-checked', 'ariaChecked', elem)) {
scope.$watch(ngAriaWatchModelValue, shape === 'radio' ?
getRadioReaction() : ngAriaCheckboxReaction);
}
break;
case 'range':
if (shouldAttachRole(shape, elem)) {
elem.attr('role', 'slider');
}
if ($aria.config('ariaValue')) {
var needsAriaValuemin = !elem.attr('aria-valuemin') &&
(attr.hasOwnProperty('min') || attr.hasOwnProperty('ngMin'));
var needsAriaValuemax = !elem.attr('aria-valuemax') &&
(attr.hasOwnProperty('max') || attr.hasOwnProperty('ngMax'));
var needsAriaValuenow = !elem.attr('aria-valuenow');
if (needsAriaValuemin) {
attr.$observe('min', function ngAriaValueMinReaction(newVal) {
elem.attr('aria-valuemin', newVal);
});
}
if (needsAriaValuemax) {
attr.$observe('max', function ngAriaValueMinReaction(newVal) {
elem.attr('aria-valuemax', newVal);
});
}
if (needsAriaValuenow) {
scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) {
elem.attr('aria-valuenow', newVal);
});
}
}
break;
case 'multiline':
if (shouldAttachAttr('aria-multiline', 'ariaMultiline', elem)) {
elem.attr('aria-multiline', true);
}
break;
}
if (needsTabIndex) {
elem.attr('tabindex', 0);
}
if (ngModel.$validators.required && shouldAttachAttr('aria-required', 'ariaRequired', elem)) {
scope.$watch(function ngAriaRequiredWatch() {
return ngModel.$error.required;
}, function ngAriaRequiredReaction(newVal) {
elem.attr('aria-required', !!newVal);
});
}
if (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem)) {
scope.$watch(function ngAriaInvalidWatch() {
return ngModel.$invalid;
}, function ngAriaInvalidReaction(newVal) {
elem.attr('aria-invalid', !!newVal);
});
}
}
};
}
};
}])
.directive('ngDisabled', ['$aria', function($aria) {
return $aria.$$watchExpr('ngDisabled', 'aria-disabled');
}])
.directive('ngMessages', function() {
return {
restrict: 'A',
require: '?ngMessages',
link: function(scope, elem, attr, ngMessages) {
if (!elem.attr('aria-live')) {
elem.attr('aria-live', 'assertive');
}
}
};
})
.directive('ngClick',['$aria', '$parse', function($aria, $parse) {
return {
restrict: 'A',
compile: function(elem, attr) {
var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true);
return function(scope, elem, attr) {
var nodeBlackList = ['BUTTON', 'A', 'INPUT', 'TEXTAREA'];
function isNodeOneOf(elem, nodeTypeArray) {
if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) {
return true;
}
}
if ($aria.config('bindRoleForClick')
&& !elem.attr('role')
&& !isNodeOneOf(elem, nodeBlackList)) {
elem.attr('role', 'button');
}
if ($aria.config('tabindex') && !elem.attr('tabindex')) {
elem.attr('tabindex', 0);
}
if ($aria.config('bindKeypress') && !attr.ngKeypress && !isNodeOneOf(elem, nodeBlackList)) {
elem.on('keypress', function(event) {
var keyCode = event.which || event.keyCode;
if (keyCode === 32 || keyCode === 13) {
scope.$apply(callback);
}
function callback() {
fn(scope, { $event: event });
}
});
}
};
}
};
}])
.directive('ngDblclick', ['$aria', function($aria) {
return function(scope, elem, attr) {
if ($aria.config('tabindex') && !elem.attr('tabindex')) {
elem.attr('tabindex', 0);
}
};
}]);
})(window, window.angular);
+13
View File
@@ -0,0 +1,13 @@
/*
AngularJS v1.4.3
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
(function(s,n,t){'use strict';n.module("ngAria",["ng"]).provider("$aria",function(){function a(a,f,l){return function(m,d,e){var b=e.$normalize(f);c[b]&&!e[b]&&m.$watch(e[a],function(b){b=l?!b:!!b;d.attr(f,b)})}}var c={ariaHidden:!0,ariaChecked:!0,ariaDisabled:!0,ariaRequired:!0,ariaInvalid:!0,ariaMultiline:!0,ariaValue:!0,tabindex:!0,bindKeypress:!0,bindRoleForClick:!0};this.config=function(a){c=n.extend(c,a)};this.$get=function(){return{config:function(a){return c[a]},$$watchExpr:a}}}).directive("ngShow",
["$aria",function(a){return a.$$watchExpr("ngShow","aria-hidden",!0)}]).directive("ngHide",["$aria",function(a){return a.$$watchExpr("ngHide","aria-hidden",!1)}]).directive("ngModel",["$aria",function(a){function c(c,m,d){return a.config(m)&&!d.attr(c)}function k(a,c){return!c.attr("role")&&c.attr("type")===a&&"INPUT"!==c[0].nodeName}function f(a,c){var d=a.type,e=a.role;return"checkbox"===(d||e)||"menuitemcheckbox"===e?"checkbox":"radio"===(d||e)||"menuitemradio"===e?"radio":"range"===d||"progressbar"===
e||"slider"===e?"range":"textbox"===(d||e)||"TEXTAREA"===c[0].nodeName?"multiline":""}return{restrict:"A",require:"?ngModel",priority:200,compile:function(l,m){var d=f(m,l);return{pre:function(a,b,c,g){"checkbox"===d&&"checkbox"!==c.type&&(g.$isEmpty=function(b){return!1===b})},post:function(e,b,h,g){function f(){return g.$modelValue}function m(){return p?(p=!1,function(a){a=h.value==g.$viewValue;b.attr("aria-checked",a);b.attr("tabindex",0-!a)}):function(a){b.attr("aria-checked",h.value==g.$viewValue)}}
function l(){b.attr("aria-checked",!g.$isEmpty(g.$viewValue))}var p=c("tabindex","tabindex",b);switch(d){case "radio":case "checkbox":k(d,b)&&b.attr("role",d);c("aria-checked","ariaChecked",b)&&e.$watch(f,"radio"===d?m():l);break;case "range":k(d,b)&&b.attr("role","slider");if(a.config("ariaValue")){var n=!b.attr("aria-valuemin")&&(h.hasOwnProperty("min")||h.hasOwnProperty("ngMin")),q=!b.attr("aria-valuemax")&&(h.hasOwnProperty("max")||h.hasOwnProperty("ngMax")),r=!b.attr("aria-valuenow");n&&h.$observe("min",
function(a){b.attr("aria-valuemin",a)});q&&h.$observe("max",function(a){b.attr("aria-valuemax",a)});r&&e.$watch(f,function(a){b.attr("aria-valuenow",a)})}break;case "multiline":c("aria-multiline","ariaMultiline",b)&&b.attr("aria-multiline",!0)}p&&b.attr("tabindex",0);g.$validators.required&&c("aria-required","ariaRequired",b)&&e.$watch(function(){return g.$error.required},function(a){b.attr("aria-required",!!a)});c("aria-invalid","ariaInvalid",b)&&e.$watch(function(){return g.$invalid},function(a){b.attr("aria-invalid",
!!a)})}}}}}]).directive("ngDisabled",["$aria",function(a){return a.$$watchExpr("ngDisabled","aria-disabled")}]).directive("ngMessages",function(){return{restrict:"A",require:"?ngMessages",link:function(a,c,k,f){c.attr("aria-live")||c.attr("aria-live","assertive")}}}).directive("ngClick",["$aria","$parse",function(a,c){return{restrict:"A",compile:function(k,f){var l=c(f.ngClick,null,!0);return function(c,d,e){function b(a,b){if(-1!==b.indexOf(a[0].nodeName))return!0}var f=["BUTTON","A","INPUT","TEXTAREA"];
!a.config("bindRoleForClick")||d.attr("role")||b(d,f)||d.attr("role","button");a.config("tabindex")&&!d.attr("tabindex")&&d.attr("tabindex",0);if(a.config("bindKeypress")&&!e.ngKeypress&&!b(d,f))d.on("keypress",function(a){function b(){l(c,{$event:a})}var d=a.which||a.keyCode;32!==d&&13!==d||c.$apply(b)})}}}}]).directive("ngDblclick",["$aria",function(a){return function(c,k,f){a.config("tabindex")&&!k.attr("tabindex")&&k.attr("tabindex",0)}}])})(window,window.angular);
//# sourceMappingURL=angular-aria.min.js.map
@@ -0,0 +1,8 @@
{
"version":3,
"file":"angular-aria.min.js",
"lineCount":12,
"mappings":"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 truncated
"sources":["angular-aria.js"],
"names":["window","angular","undefined","module","provider","ngAriaModule","$AriaProvider","watchExpr","attrName","ariaAttr","negate","scope","elem","attr","ariaCamelName","$normalize","config","$watch","boolVal","ariaHidden","ariaChecked","ariaDisabled","ariaRequired","ariaInvalid","ariaMultiline","ariaValue","tabindex","bindKeypress","bindRoleForClick","this.config","newConfig","extend","$get","this.$get","key","$$watchExpr","directive","$aria","shouldAttachAttr","normalizedAttr","shouldAttachRole","role","nodeName","getShape","type","restrict","require","priority","compile","shape","pre","ngModel","$isEmpty","ngModel.$isEmpty","value","post","ngAriaWatchModelValue","$modelValue","getRadioReaction","needsTabIndex","ngAriaRadioReaction","newVal","$viewValue","ngAriaCheckboxReaction","needsAriaValuemin","hasOwnProperty","needsAriaValuemax","needsAriaValuenow","$observe","ngAriaValueMinReaction","ngAriaValueNowReaction","$validators","required","ngAriaRequiredWatch","$error","ngAriaRequiredReaction","ngAriaInvalidWatch","$invalid","ngAriaInvalidReaction","link","ngMessages","$parse","fn","ngClick","isNodeOneOf","nodeTypeArray","indexOf","nodeBlackList","ngKeypress","on","event","callback","$event","keyCode","which","$apply"]
}
@@ -0,0 +1,7 @@
/*
angular-file-upload v2.1.1
https://github.com/nervgh/angular-file-upload
*/
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):"object"==typeof exports?exports["angular-file-upload"]=t():e["angular-file-upload"]=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return e[r].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=r(n(2)),o=r(n(3)),s=r(n(4)),a=r(n(5)),u=r(n(6)),l=r(n(7)),c=r(n(1)),f=r(n(8)),p=r(n(9)),d=r(n(10)),v=r(n(11)),h=r(n(12));angular.module(i.name,[]).value("fileUploaderOptions",o).factory("FileUploader",s).factory("FileLikeObject",a).factory("FileItem",u).factory("FileDirective",l).factory("FileSelect",c).factory("FileDrop",f).factory("FileOver",p).directive("nvFileSelect",d).directive("nvFileDrop",v).directive("nvFileOver",h).run(["FileUploader","FileLikeObject","FileItem","FileDirective","FileSelect","FileDrop","FileOver",function(e,t,n,r,i,o,s){e.FileLikeObject=t,e.FileItem=n,e.FileDirective=r,e.FileSelect=i,e.FileDrop=o,e.FileOver=s}])},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=function(){function e(e,t){for(var n in t){var r=t[n];r.configurable=!0,r.value&&(r.writable=!0)}Object.defineProperties(e,t)}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=function u(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t);if(void 0===r){var i=Object.getPrototypeOf(e);return null===i?void 0:u(i,t,n)}if("value"in r&&r.writable)return r.value;var o=r.get;return void 0===o?void 0:o.call(n)},s=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(e.__proto__=t)},a=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")};r(n(2));e.exports=function(e){var t=function(e){function t(e){a(this,t),this.events={$destroy:"destroy",change:"onChange"},this.prop="select",o(Object.getPrototypeOf(t.prototype),"constructor",this).call(this,e),this.uploader.isHTML5||this.element.removeAttr("multiple"),this.element.prop("value",null)}return s(t,e),i(t,{getOptions:{value:function(){}},getFilters:{value:function(){}},isEmptyAfterSelection:{value:function(){return!!this.element.attr("multiple")}},onChange:{value:function(){var e=this.uploader.isHTML5?this.element[0].files:this.element[0],t=this.getOptions(),n=this.getFilters();this.uploader.isHTML5||this.destroy(),this.uploader.addToQueue(e,t,n),this.isEmptyAfterSelection()&&this.element.prop("value",null)}}}),t}(e);return t},e.exports.$inject=["FileDirective"]},function(e,t){e.exports={name:"angularFileUpload"}},function(e,t){"use strict";e.exports={url:"/",alias:"file",headers:{},queue:[],progress:0,autoUpload:!1,removeAfterUpload:!1,method:"POST",filters:[],formData:[],queueLimit:Number.MAX_VALUE,withCredentials:!1}},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=function(){function e(e,t){for(var n in t){var r=t[n];r.configurable=!0,r.value&&(r.writable=!0)}Object.defineProperties(e,t)}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},s=(r(n(2)),angular.copy),a=angular.extend,u=angular.forEach,l=angular.isObject,c=angular.isNumber,f=angular.isDefined,p=angular.isArray,d=angular.element;e.exports=function(e,t,n,r,v,h){var m=r.File,_=r.FormData,g=function(){function r(t){o(this,r);var n=s(e);a(this,n,t,{isUploading:!1,_nextIndex:0,_failFilterIndex:-1,_directives:{select:[],drop:[],over:[]}}),this.filters.unshift({name:"queueLimit",fn:this._queueLimitFilter}),this.filters.unshift({name:"folder",fn:this._folderFilter})}return i(r,{addToQueue:{value:function(e,t,n){var r=this,i=this.isArrayLikeObject(e)?e:[e],o=this._getFilters(n),s=this.queue.length,a=[];u(i,function(e){var n=new v(e);if(r._isValidFile(n,o,t)){var i=new h(r,e,t);a.push(i),r.queue.push(i),r._onAfterAddingFile(i)}else{var s=o[r._failFilterIndex];r._onWhenAddingFileFailed(n,s,t)}}),this.queue.length!==s&&(this._onAfterAddingAll(a),this.progress=this._getTotalProgress()),this._render(),this.autoUpload&&this.uploadAll()}},removeFromQueue:{value:function(e){var t=this.getIndexOfItem(e),n=this.queue[t];n.isUploading&&n.cancel(),this.queue.splice(t,1),n._destroy(),this.progress=this._getTotalProgress()}},clearQueue:{value:function(){for(;this.queue.length;)this.queue[0].remove();this.progress=0}},uploadItem:{value:function(e){var t=this.getIndexOfItem(e),n=this.queue[t],r=this.isHTML5?"_xhrTransport":"_iframeTransport";n._prepareToUploading(),this.isUploading||(this.isUploading=!0,this[r](n))}},cancelItem:{value:function(e){var t=this.getIndexOfItem(e),n=this.queue[t],r=tLine truncated
//# sourceMappingURL=angular-file-upload.min.js.map
File diff suppressed because it is too large. Load diff
+15
View File
@@ -0,0 +1,15 @@
/*!
* Angular Material Design
* https://github.com/angular/material
* @license MIT
* v0.10.1-master-514927a
*/
!function(e,t,n){"use strict";!function(){t.module("ngMaterial",["ng","ngAnimate","ngAria","material.core","material.core.gestures","material.core.theming.palette","material.core.theming","material.animate","material.components.autocomplete","material.components.backdrop","material.components.bottomSheet","material.components.button","material.components.card","material.components.checkbox","material.components.chips","material.components.content","material.components.dialog","material.components.divider","material.components.fabActions","material.components.fabSpeedDial","material.components.fabToolbar","material.components.fabTrigger","material.components.gridList","material.components.icon","material.components.input","material.components.list","material.components.menu","material.components.progressCircular","material.components.progressLinear","material.components.radioButton","material.components.select","material.components.sidenav","material.components.slider","material.components.sticky","material.components.subheader","material.components.swipe","material.components.switch","material.components.tabs","material.components.toast","material.components.toolbar","material.components.tooltip","material.components.virtualRepeat","material.components.whiteframe"])}(),function(){function e(e,t){e.decorator("$$rAF",["$delegate",n]),t.theme("default").primaryPalette("indigo").accentPalette("pink").warnPalette("red").backgroundPalette("grey")}function n(e){return e.throttle=function(t){var n,o,r,i;return function(){n=arguments,i=this,r=t,o||(o=!0,e(function(){r.apply(i,Array.prototype.slice.call(n)),o=!1}))}},e}t.module("material.core",["ngAnimate","material.animate","material.core.gestures","material.core.theming"]).config(e),e.$inject=["$provide","$mdThemingProvider"]}(),function(){function e(e){function t(e){return n?"webkit"+e.charAt(0).toUpperCase()+e.substring(1):e}var n=/webkit/i.test(e.vendorPrefix);return{KEY_CODE:{ENTER:13,ESCAPE:27,SPACE:32,LEFT_ARROW:37,UP_ARROW:38,RIGHT_ARROW:39,DOWN_ARROW:40,TAB:9,BACKSPACE:8,DELETE:46},CSS:{TRANSITIONEND:"transitionend"+(n?" webkitTransitionEnd":""),ANIMATIONEND:"animationend"+(n?" webkitAnimationEnd":""),TRANSFORM:t("transform"),TRANSFORM_ORIGIN:t("transformOrigin"),TRANSITION:t("transition"),TRANSITION_DURATION:t("transitionDuration"),ANIMATION_PLAY_STATE:t("animationPlayState"),ANIMATION_DURATION:t("animationDuration"),ANIMATION_NAME:t("animationName"),ANIMATION_TIMING:t("animationTimingFunction"),ANIMATION_DIRECTION:t("animationDirection")},MEDIA:{sm:"(max-width: 599px)","gt-sm":"(min-width: 600px)",md:"(min-width: 600px) and (max-width: 959px)","gt-md":"(min-width: 960px)",lg:"(min-width: 960px) and (max-width: 1199px)","gt-lg":"(min-width: 1200px)"},MEDIA_PRIORITY:["gt-lg","lg","gt-md","md","gt-sm","sm"]}}t.module("material.core").factory("$mdConstant",e),e.$inject=["$sniffer"]}(),function(){function e(e,n){function o(){return[].concat(E)}function r(){return E.length}function i(e){return E.length&&e>-1&&e<E.length}function a(e){return e?i(u(e)+1):!1}function d(e){return e?i(u(e)-1):!1}function c(e){return i(e)?E[e]:null}function l(e,t){return E.filter(function(n){return n[e]===t})}function s(e,n){return e?(t.isNumber(n)||(n=E.length),E.splice(n,0,e),u(e)):-1}function m(e){p(e)&&E.splice(u(e),1)}function u(e){return E.indexOf(e)}function p(e){return e&&u(e)>-1}function f(){return E.length?E[0]:null}function h(){return E.length?E[E.length-1]:null}function b(e,o,r,a){r=r||g;for(var d=u(o);;){if(!i(d))return null;var c=d+(e?-1:1),l=null;if(i(c)?l=E[c]:n&&(l=e?h():f(),c=u(l)),null===l||c===a)return null;if(r(l))return l;t.isUndefined(a)&&(a=c),d=c}}var g=function(){return!0};e&&!t.isArray(e)&&(e=Array.prototype.slice.call(e)),n=!!n;var E=e||[];return{items:o,count:r,inRange:i,contains:p,indexOf:u,itemAt:c,findBy:l,add:s,remove:m,first:f,last:h,next:t.bind(null,b,!1),previous:t.bind(null,b,!0),hasPrevious:d,hasNext:a}}t.module("material.core").config(["$provide",function(t){t.decorator("$mdUtil",["$delegate",function(t){return t.iterator=e,t}])}])}(),function(){function e(e,n,o){function r(e){var n=u[e];t.isUndefined(n)&&(n=u[e]=i(e));var o=f[n];return t.isUndefined(o)&&(o=a(n)),o}function i(t){return e.MEDIA[t]||("("!==t.charAt(0)?"("+t+")":t)}function a(e){var t=p[e]=o.matchMedia(e);return t.addListener(d),f[t.media]=!!t.matches}function d(e){n.$evalAsync(function(){f[e.media]=!!e.matches})}function c(e){return p[e]}function l(t,n){for(var o=0;o<e.MEDIA_PRIORITY.length;o++){var r=e.MEDIA_PRIORITY[o];if(p[u[r]].matches){var i=m(t,n+"-"+r);if(t[i])return t[i]}}return t[m(t,n)]}function s(n,o,r){var i=[];return n.forEach(function(n){var a=m(o,n);o[a]&&i.push(o.$observe(a,t.bind(void 0,r,null)));for(var d in e.MEDIA){if(a=m(o,n+"-"+d),!o[a])return;i.push(o.$observe(a,t.bind(void 0,r,d)))}}),function(){i.forEach(function(e){e()})}}function m(e,t){return h[t]||(h[t]=e.$normalize(t))}var u={},p={},f={},h={};return r.getResponsiveAttribute=l,r.getQuery=c,r.watchRespLine truncated
contrastDefaultColor:"dark",contrastLightColors:"800 900",contrastStrongLightColors:"800 900"},lime:{50:"#f9fbe7",100:"#f0f4c3",200:"#e6ee9c",300:"#dce775",400:"#d4e157",500:"#cddc39",600:"#c0ca33",700:"#afb42b",800:"#9e9d24",900:"#827717",A100:"#f4ff81",A200:"#eeff41",A400:"#c6ff00",A700:"#aeea00",contrastDefaultColor:"dark",contrastLightColors:"900",contrastStrongLightColors:"900"},yellow:{50:"#fffde7",100:"#fff9c4",200:"#fff59d",300:"#fff176",400:"#ffee58",500:"#ffeb3b",600:"#fdd835",700:"#fbc02d",800:"#f9a825",900:"#f57f17",A100:"#ffff8d",A200:"#ffff00",A400:"#ffea00",A700:"#ffd600",contrastDefaultColor:"dark"},amber:{50:"#fff8e1",100:"#ffecb3",200:"#ffe082",300:"#ffd54f",400:"#ffca28",500:"#ffc107",600:"#ffb300",700:"#ffa000",800:"#ff8f00",900:"#ff6f00",A100:"#ffe57f",A200:"#ffd740",A400:"#ffc400",A700:"#ffab00",contrastDefaultColor:"dark"},orange:{50:"#fff3e0",100:"#ffe0b2",200:"#ffcc80",300:"#ffb74d",400:"#ffa726",500:"#ff9800",600:"#fb8c00",700:"#f57c00",800:"#ef6c00",900:"#e65100",A100:"#ffd180",A200:"#ffab40",A400:"#ff9100",A700:"#ff6d00",contrastDefaultColor:"dark",contrastLightColors:"800 900",contrastStrongLightColors:"800 900"},"deep-orange":{50:"#fbe9e7",100:"#ffccbc",200:"#ffab91",300:"#ff8a65",400:"#ff7043",500:"#ff5722",600:"#f4511e",700:"#e64a19",800:"#d84315",900:"#bf360c",A100:"#ff9e80",A200:"#ff6e40",A400:"#ff3d00",A700:"#dd2c00",contrastDefaultColor:"light",contrastDarkColors:"50 100 200 300 400 A100 A200",contrastStrongLightColors:"500 600 700 800 900 A400 A700"},brown:{50:"#efebe9",100:"#d7ccc8",200:"#bcaaa4",300:"#a1887f",400:"#8d6e63",500:"#795548",600:"#6d4c41",700:"#5d4037",800:"#4e342e",900:"#3e2723",A100:"#d7ccc8",A200:"#bcaaa4",A400:"#8d6e63",A700:"#5d4037",contrastDefaultColor:"light",contrastDarkColors:"50 100 200",contrastStrongLightColors:"300 400"},grey:{50:"#fafafa",100:"#f5f5f5",200:"#eeeeee",300:"#e0e0e0",400:"#bdbdbd",500:"#9e9e9e",600:"#757575",700:"#616161",800:"#424242",900:"#212121",1000:"#000000",A100:"#ffffff",A200:"#eeeeee",A400:"#bdbdbd",A700:"#616161",contrastDefaultColor:"dark",contrastLightColors:"600 700 800 900"},"blue-grey":{50:"#eceff1",100:"#cfd8dc",200:"#b0bec5",300:"#90a4ae",400:"#78909c",500:"#607d8b",600:"#546e7a",700:"#455a64",800:"#37474f",900:"#263238",A100:"#cfd8dc",A200:"#b0bec5",A400:"#78909c",A700:"#455a64",contrastDefaultColor:"light",contrastDarkColors:"50 100 200 300",contrastStrongLightColors:"400 500"}})}(),function(){function e(e){function o(e,t){return t=t||{},s[e]=a(e,t),g}function r(e,n){return a(e,t.extend({},s[e]||{},n))}function a(e,t){var n=T.filter(function(e){return!t[e]});if(n.length)throw new Error("Missing colors %1 in palette %2!".replace("%1",n.join(", ")).replace("%2",e));return t}function d(e,n){if(m[e])return m[e];n=n||"default";var o="string"==typeof n?m[n]:n,r=new c(e);return o&&t.forEach(o.colors,function(e,n){r.colors[n]={name:e.name,hues:t.extend({},e.hues)}}),m[e]=r,r}function c(e){function n(e){if(e=0===arguments.length?!0:!!e,e!==o.isDark){o.isDark=e,o.foregroundPalette=o.isDark?f:p,o.foregroundShadow=o.isDark?h:b;var n=o.isDark?C:A,r=o.isDark?A:C;return t.forEach(n,function(e,t){var n=o.colors[t],i=r[t];if(n)for(var a in n.hues)n.hues[a]===i[a]&&(n.hues[a]=e[a])}),o}}var o=this;o.name=e,o.colors={},o.dark=n,n(!1),$.forEach(function(e){var n=(o.isDark?C:A)[e];o[e+"Palette"]=function(r,i){var a=o.colors[e]={name:r,hues:t.extend({},n,i)};return Object.keys(a.hues).forEach(function(e){if(!n[e])throw new Error("Invalid hue name '%1' in theme %2's %3 color %4. Available hue names: %4".replace("%1",e).replace("%2",o.name).replace("%3",r).replace("%4",Object.keys(n).join(", ")))}),Object.keys(a.hues).map(function(e){return a.hues[e]}).forEach(function(t){if(-1==T.indexOf(t))throw new Error("Invalid hue value '%1' in theme %2's %3 color %4. Available hue values: %5".replace("%1",t).replace("%2",o.name).replace("%3",e).replace("%4",r).replace("%5",T.join(", ")))}),o},o[e+"Color"]=function(){var t=Array.prototype.slice.call(arguments);return console.warn("$mdThemingProviderTheme."+e+"Color() has been deprecated. Use $mdThemingProviderTheme."+e+"Palette() instead."),o[e+"Palette"].apply(o,t)}})}function u(e,o){function r(e){return e===n||""===e?!0:i.THEMES[e]!==n}function i(t,o){o===n&&(o=t,t=n),t===n&&(t=e),i.inherit(o,o)}return i.inherit=function(n,i){function a(e){r(e)||o.warn("Attempted to use unregistered theme '"+e+"'. Register it with $mdThemingProvider.theme().");var t=n.data("$mdThemeName");t&&n.removeClass("md-"+t+"-theme"),n.addClass("md-"+e+"-theme"),n.data("$mdThemeName",e),d&&n.data("$mdThemeController",d)}var d=i.controller("mdTheme"),c=n.attr("md-theme-watch");if((v||t.isDefined(c))&&"false"!=c){var l=e.$watch(function(){return d&&d.$mdTheme||E},a);n.on("$destroy",l)}else{var s=d&&d.$mdTheme||E;a(s)}},i.THEMES=t.extend({},m),i.defaultTheme=function(){return E},i.registered=r,i}s={},m={};var g,E="default",v=!1;return t.extend(s,e),u.$inject=["$rootScope","$log"],g={definePalette:o,extendPalette:r,theme:d,Line truncated
scope:{isOpen:"=?mdOpen"},bindToController:!0,controller:e,controllerAs:"vm",link:t}}function o(){function n(n,o,r){var i=n[0],a=n.controller("mdFabToolbar"),d=i.querySelector(".md-fab-toolbar-background"),c=i.querySelector("md-fab-trigger button"),l=i.querySelector("md-fab-trigger button md-icon"),s=n.find("md-fab-actions").children();if(c&&d){var m=e.getComputedStyle(c).getPropertyValue("background-color"),u=i.offsetWidth,p=(i.offsetHeight,2*u);d.style.backgroundColor=m,d.style.borderRadius=u+"px",a.isOpen?(d.style.width=p+"px",d.style.height=p+"px",d.style.top=-(p/2)+"px",n.hasClass("md-left")&&(d.style.left=-(p/2)+"px",d.style.right=null),n.hasClass("md-right")&&(d.style.right=-(p/2)+"px",d.style.left=null),d.style.transitionDelay="0ms",l&&(l.style.transitionDelay=".3s"),t.forEach(s,function(e,t){e.style.transitionDelay=25*(s.length-t)+"ms"})):(d.style.width=c.offsetWidth+"px",d.style.height=c.offsetHeight+"px",d.style.top="0px",n.hasClass("md-left")&&(d.style.left="0px",d.style.right=null),n.hasClass("md-right")&&(d.style.right="0px",d.style.left=null),d.style.transitionDelay="200ms",l&&(l.style.transitionDelay="0ms"),t.forEach(s,function(e,t){e.style.transitionDelay=25*t+"ms"}))}}return{addClass:function(e,t,o){n(e,t,o),o()},removeClass:function(e,t,o){n(e,t,o),o()}}}t.module("material.components.fabToolbar",["material.core","material.components.fabTrigger","material.components.fabActions"]).directive("mdFabToolbar",n).animation(".md-fab-toolbar",o).service("mdFabToolbarAnimation",o)}()}(),function(){!function(){function e(){return{restrict:"E",require:["^?mdFabSpeedDial","^?mdFabToolbar"],link:function(e,n,o,r){var i=r[0]||r[1];i&&t.forEach(n.children(),function(e){t.element(e).on("focus",i.open),t.element(e).on("blur",i.close)})}}}t.module("material.components.fabTrigger",["material.core"]).directive("mdFabTrigger",e)}()}(),function(){function e(e,o,r,i){function a(n,a,d,c){function l(){for(var e in o.MEDIA)i(e),i.getQuery(o.MEDIA[e]).addListener(C);return i.watchResponsiveAttributes(["md-cols","md-row-height"],d,m)}function s(){c.layoutDelegate=t.noop,T();for(var e in o.MEDIA)i.getQuery(o.MEDIA[e]).removeListener(C)}function m(e){null==e?c.invalidateLayout():i(e)&&c.invalidateLayout()}function u(e){var o=b(),i={tileSpans:g(o),colCount:E(),rowMode:M(),rowHeight:$(),gutter:v()};if(e||!t.equals(i,y)){var d=r(i.colCount,i.tileSpans,o).map(function(e,n){return{grid:{element:a,style:h(i.colCount,n,i.gutter,i.rowMode,i.rowHeight)},tiles:e.map(function(e,n){return{element:t.element(o[n]),style:f(e.position,e.spans,i.colCount,i.rowCount,i.gutter,i.rowMode,i.rowHeight)}})}}).reflow().performance();n.mdOnLayout({$event:{performance:d}}),y=i}}function p(e){return w+e+k}function f(e,t,n,o,r,i,a){var d=1/n*100,c=(n-1)/n,l=x({share:d,gutterShare:c,gutter:r}),s={left:N({unit:l,offset:e.col,gutter:r}),width:_({unit:l,span:t.col,gutter:r}),paddingTop:"",marginTop:"",top:"",height:""};switch(i){case"fixed":s.top=N({unit:a,offset:e.row,gutter:r}),s.height=_({unit:a,span:t.row,gutter:r});break;case"ratio":var m=d/a,u=x({share:m,gutterShare:c,gutter:r});s.paddingTop=_({unit:u,span:t.row,gutter:r}),s.marginTop=N({unit:u,offset:e.row,gutter:r});break;case"fit":var p=(o-1)/o,m=1/o*100,u=x({share:m,gutterShare:p,gutter:r});s.top=N({unit:u,offset:e.row,gutter:r}),s.height=_({unit:u,span:t.row,gutter:r})}return s}function h(e,t,n,o,r){var i={height:"",paddingBottom:""};switch(o){case"fixed":i.height=_({unit:r,span:t,gutter:n});break;case"ratio":var a=1===e?0:(e-1)/e,d=1/e*100,c=d*(1/r),l=x({share:c,gutterShare:a,gutter:n});i.paddingBottom=_({unit:l,span:t,gutter:n});break;case"fit":}return i}function b(){return[].filter.call(a.children(),function(e){return"MD-GRID-TILE"==e.tagName})}function g(e){return[].map.call(e,function(e){var n=t.element(e).controller("mdGridTile");return{row:parseInt(i.getResponsiveAttribute(n.$attrs,"md-rowspan"),10)||1,col:parseInt(i.getResponsiveAttribute(n.$attrs,"md-colspan"),10)||1}})}function E(){var e=parseInt(i.getResponsiveAttribute(d,"md-cols"),10);if(isNaN(e))throw"md-grid-list: md-cols attribute was not found, or contained a non-numeric value";return e}function v(){return A(i.getResponsiveAttribute(d,"md-gutter")||1)}function $(){var e=i.getResponsiveAttribute(d,"md-row-height");switch(M()){case"fixed":return A(e);case"ratio":var t=e.split(":");return parseFloat(t[0])/parseFloat(t[1]);case"fit":return 0}}function M(){var e=i.getResponsiveAttribute(d,"md-row-height");return"fit"==e?"fit":-1!==e.indexOf(":")?"ratio":"fixed"}function A(e){return/\D$/.test(e)?e:e+"px"}a.attr("role","list"),c.layoutDelegate=u;var C=t.bind(c,c.invalidateLayout),T=l();n.$on("$destroy",s);var y,w=e.startSymbol(),k=e.endSymbol(),x=e(p("share")+"% - ("+p("gutter")+" * "+p("gutterShare")+")"),N=e("calc(("+p("unit")+" + "+p("gutter")+") * "+p("offset")+")"),_=e("calc(("+p("unit")+") * "+p("span")+" + ("+p("span")+" - 1) * "+p("gutter")+")")}return{restrict:"E",controller:n,scope:{mdOnLayout:"&"},link:a}}function n(e)Line truncated
a.find("md-option").attr("ng-show","$$loadingAsyncDone")),l.name){var m=t.element('<select class="md-visually-hidden">');m.attr({name:"."+l.name,"ng-model":l.ngModel,"aria-hidden":"true",tabindex:"-1"});var u=a.find("md-option");t.forEach(u,function(e){var n=t.element("<option>"+e.innerHTML+"</option>");e.hasAttribute("ng-value")?n.attr("ng-value",e.getAttribute("ng-value")):e.hasAttribute("value")&&n.attr("value",e.getAttribute("value")),m.append(n)}),a.parent().append(m)}var p=t.isDefined(l.multiple)?"multiple":"",f='<div class="md-select-menu-container"><md-select-menu {0}>{1}</md-select-menu></div>';return f=o.supplant(f,[p,a.html()]),a.empty().append(s),l.tabindex=l.tabindex||"0",function(a,l,s,m){function u(){var e=l.attr("placeholder");!e&&M&&M.label&&(e=M.label.text()),i.expect(l,"aria-label",e)}function p(){x&&(_=_||x.find("md-select-menu").controller("mdSelectMenu"),A.setLabelText(_.selectedLabels()))}function h(){M&&M.setHasValue(_.selectedLabels().length>0||(l[0].validity||{}).badInput)}function b(){x=t.element(f);var e=x.find("md-select-menu");e.data("$ngModelController",C),e.data("$mdSelectController",A),N=a.$new(),r.inherit(x,l),x[0].setAttribute("class",x[0].getAttribute("class")+" "+l.attr("md-container-class")),x=d(x)(N),_=x.find("md-select-menu").controller("mdSelectMenu")}function g(e){var n=[32,13,38,40];if(-1!=n.indexOf(e.keyCode))e.preventDefault(),E(e);else if(e.keyCode<=90&&e.keyCode>=31){e.preventDefault();var o=_.optNodeForKeyboardSearch(e);if(!o)return;var r=t.element(o).controller("mdOption");_.isMultiple||_.deselect(Object.keys(_.selected)[0]),_.select(r.hashKey,r.value),_.refreshViewValue(),C.$render()}}function E(){a.$apply("isOpen = true"),e.show({scope:N,preserveScope:!0,skipCompile:!0,element:x,target:l[0],hasBackdrop:!0,loadingAsync:s.mdOnOpen?a.$eval(s.mdOnOpen)||!0:!1}).then(function(){v=!1})}var v,$,M=m[0],A=m[1],C=m[2],T=m[3],y=l.find("md-select-value"),w=t.isDefined(s.readonly);if(M){var k=M.isErrorGetter||function(){return C.$invalid&&C.$touched};if(M.input)throw new Error("<md-input-container> can only have *one* child <input>, <textarea> or <select> element!");M.input=l,M.label||i.expect(l,"aria-label",l.attr("placeholder")),a.$watch(k,M.setInvalid)}var x,N,_;if(b(),r(l),s.name&&T){var H=l.parent()[0].querySelector('select[name=".'+s.name+'"]'),S=t.element(H).controller();S&&T.$removeControl(S)}var I=C.$render;C.$render=function(){I(),p(),h()},A.setLabelText=function(e){A.setIsPlaceholder(!e);var t=s.placeholder||(M&&M.label?M.label.text():"");e=e||t||"";var n=y.children().eq(0);n.text(e)},A.setIsPlaceholder=function(e){e?(y.addClass("md-select-placeholder"),M&&M.label&&M.label.addClass("md-placeholder md-static")):(y.removeClass("md-select-placeholder"),M&&M.label&&M.label.removeClass("md-placeholder"))},w||l.on("focus",function(e){M&&M.element.hasClass("md-input-has-value")&&M.setFocused(!0)}).on("blur",function(e){M&&M.setFocused(!1),h()}),A.triggerClose=function(){c(s.mdOnClose)(a)},a.$$postDigest(function(){u(),p()});var D;s.$observe("ngMultiple",function(e){D&&D();var t=c(e);D=a.$watch(function(){return t(a)},function(e,t){(e!==n||t!==n)&&(e?l.attr("multiple","multiple"):l.removeAttr("multiple"),x&&(_.setMultiple(e),I=C.$render,C.$render=function(){I(),p()},_.refreshViewValue(),C.$render()))})}),s.$observe("disabled",function(e){"string"==typeof e&&(e=!0),($===n||$!==e)&&($=e,e?(l.attr({tabindex:-1,"aria-disabled":"true"}),l.off("click",E),l.off("keydown",g)):(l.attr({tabindex:s.tabindex,"aria-disabled":"false"}),l.on("click",E),l.on("keydown",g)))}),s.disabled||s.ngDisabled||(l.attr({tabindex:s.tabindex,"aria-disabled":"false"}),l.on("click",E),l.on("keydown",g));var O={role:"combobox","aria-expanded":"false"};l[0].hasAttribute("id")||(O.id="select_"+o.nextUid()),l.attr(O),a.$on("$destroy",function(){v?e.hide()["finally"](function(){x.remove()}):x.remove(),M&&(M.setFocused(!1),M.setHasValue(!1),M.input=null)})}}return{restrict:"E",require:["^?mdInputContainer","mdSelect","ngModel","?^form"],compile:l,controller:function(){}}}function o(e,o,r){function i(e,n,i,a){function d(){n.attr({id:"select_menu_"+o.nextUid(),role:"listbox","aria-multiselectable":s.isMultiple?"true":"false"})}function c(e){(13==e.keyCode||32==e.keyCode)&&l(e)}function l(n){var r=o.getClosest(n.target,"md-option"),i=r&&t.element(r).data("$mdOptionController");if(r&&i){if(r.hasAttribute("disabled"))return n.stopImmediatePropagation(),!1;var a=s.hashGetter(i.value),d=t.isDefined(s.selected[a]);e.$apply(function(){s.isMultiple?d?s.deselect(a):s.select(a,i.value):d||(s.deselect(Object.keys(s.selected)[0]),s.select(a,i.value)),s.refreshViewValue()})}}var s=a[0],m=a[1];r(n),n.on("click",l),n.on("keypress",c),m&&s.init(m),d()}function a(r,i,a){function d(){var e=s.ngModel.$modelValue||s.ngModel.$viewValue;if(t.isArray(e)){var n=Object.keys(s.selected),o=e.map(s.hashGetter),r=n.filter(function(e){return-1===o.indexOf(e)});r.forEach(s.deselect),o.forEach(function(t,n){s.select(t,e[n])})}}functionLine truncated
C.queued||(t?(C.queued=!0,e(function(){s.visible=C.value,C.queued=!1},s.delay)):i.nextTick(function(){s.visible=!1}))}function T(){return S.append(p),M("display","none")?(s.visible=!1,void p.detach()):(w(),void t.forEach([p,x,N],function(e){c.addClass(e,"md-show")}))}function y(){var e=[];t.forEach([p,x,N],function(t){t.parent()&&t.hasClass("md-show")&&e.push(c.removeClass(t,"md-show"))}),l.all(e).then(function(){s.visible||p.detach()})}function w(){function e(){var e="left"===_||"right"===_?2*Math.sqrt(Math.pow(o.width,2)+Math.pow(o.height/2,2)):2*Math.sqrt(Math.pow(o.width/2,2)+Math.pow(o.height,2)),t="left"===_?{left:100,top:50}:"right"===_?{left:0,top:50}:"top"===_?{left:50,top:100}:{left:50,top:0};x.css({width:e+"px",height:e+"px",left:t.left+"%",top:t.top+"%"})}function t(e){var t={left:e.left,top:e.top};return t.left=Math.min(t.left,S.prop("scrollWidth")-o.width-u),t.left=Math.max(t.left,u),t.top=Math.min(t.top,S.prop("scrollHeight")-o.height-u),t.top=Math.max(t.top,u),t}function n(e){return"left"===e?{left:r.left-o.width-u,top:r.top+r.height/2-o.height/2}:"right"===e?{left:r.left+r.width+u,top:r.top+r.height/2-o.height/2}:"top"===e?{left:r.left+r.width/2-o.width/2,top:r.top-o.height-u}:{left:r.left+r.width/2-o.width/2,top:r.top+r.height+u}}var o=i.offsetRect(p,S),r=i.offsetRect(k,S),a=n(_);_?a=t(a):a.top>p.prop("offsetParent").scrollHeight-o.height-u&&(a=t(n("top"))),p.css({top:a.top+"px",left:a.left+"px"}),e()}a(p);var k=v(),x=t.element(p[0].getElementsByClassName("md-background")[0]),N=t.element(p[0].getElementsByClassName("md-content")[0]),_=f.mdDirection,H=$(),S=t.element(H||document.body),I=o.throttle(function(){s.visible&&w()});h(),E(),A(),b(),g()}var m=300,u=8;return{restrict:"E",transclude:!0,priority:210,template:' <div class="md-background"></div> <div class="md-content" ng-transclude></div>',scope:{visible:"=?mdVisible",delay:"=?mdDelay",autohide:"=?mdAutohide"},link:s}}t.module("material.components.tooltip",["material.core"]).directive("mdTooltip",e),e.$inject=["$timeout","$window","$$rAF","$document","$mdUtil","$mdTheming","$rootElement","$animate","$q"]}(),function(){function e(){return{controller:o,template:n,compile:function(e,t){e.addClass("md-virtual-repeat-container").addClass(t.hasOwnProperty("mdOrientHorizontal")?"md-orient-horizontal":"md-orient-vertical")}}}function n(e){return'<div class="md-virtual-repeat-scroller"><div class="md-virtual-repeat-sizer"></div><div class="md-virtual-repeat-offsetter">'+e[0].innerHTML+"</div></div>"}function o(e,n,o,r){this.$scope=n,this.$element=o,this.$attrs=r,this.size=0,this.scrollSize=0,this.scrollOffset=0,this.horizontal=this.$attrs.hasOwnProperty("mdOrientHorizontal"),this.repeater=null,this.autoShrink=this.$attrs.hasOwnProperty("mdAutoShrink"),this.autoShrinkMin=parseInt(this.$attrs.mdAutoShrinkMin,10)||0,this.originalSize=null,this.scroller=o[0].getElementsByClassName("md-virtual-repeat-scroller")[0],this.sizer=this.scroller.getElementsByClassName("md-virtual-repeat-sizer")[0],this.offsetter=this.scroller.getElementsByClassName("md-virtual-repeat-offsetter")[0],e(t.bind(this,this.updateSize)),r.ngHide&&n.$watch(r.ngHide,t.bind(this,function(n){n||e(t.bind(this,this.updateSize))}))}function r(e){return{controller:i,priority:1e3,require:["mdVirtualRepeat","^^mdVirtualRepeatContainer"],restrict:"A",terminal:!0,transclude:"element",compile:function(t,n){var o=n.mdVirtualRepeat,r=o.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)\s*$/),i=r[1],a=e(r[2]),d=n.mdExtraName&&e(n.mdExtraName);return function(e,t,n,o,r){o[0].link_(o[1],r,i,a,d)}}}}function i(e,t,n,o,r,i){this.$scope=e,this.$element=t,this.$attrs=n,this.$browser=o,this.$document=r,this.$$rAF=i,this.browserCheckUrlChange=o.$$checkUrlChange,this.newStartIndex=0,this.newEndIndex=0,this.startIndex=0,this.endIndex=0,this.itemSize=e.$eval(n.mdItemSize)||null,this.isFirstRender=!0,this.itemsLength=0,this.blocks={},this.pooledBlocks=[]}t.module("material.components.virtualRepeat",["material.core"]).directive("mdVirtualRepeatContainer",e).directive("mdVirtualRepeat",r);var a=1533917,d=3;o.$inject=["$$rAF","$scope","$element","$attrs"],o.prototype.register=function(e){this.repeater=e,t.element(this.scroller).on("scroll wheel touchmove touchend",t.bind(this,this.handleScroll_))},o.prototype.isHorizontal=function(){return this.horizontal},o.prototype.getSize=function(){return this.size},o.prototype.setSize_=function(e){this.size=e,this.$element[0].style[this.isHorizontal()?"width":"height"]=e+"px"},o.prototype.updateSize=function(){this.originalSize||(this.size=this.isHorizontal()?this.$element[0].clientWidth:this.$element[0].clientHeight,this.repeater&&this.repeater.containerUpdated())},o.prototype.getScrollSize=function(){return this.scrollSize},o.prototype.sizeScroller_=function(e){var t=this.isHorizontal()?"width":"height",n=this.isHorizontal()?"height":"width";if(a>e)this.sizer.style[t]=e+"px";else{this.sizer.innerHTML="",this.sizer.style[t]="auto",this.sizer.style[n]="auto";var o=MatLine truncated
}(),function(){function e(){this.selectedItem=null,this.searchText=""}t.module("material.components.chips").controller("MdContactChipsCtrl",e),e.prototype.queryContact=function(e){var n=this.contactQuery({$query:e});return this.filterSelected?n.filter(t.bind(this,this.filterSelectedContacts)):n},e.prototype.filterSelectedContacts=function(e){return-1==this.contacts.indexOf(e)}}(),function(){function e(e,t){function o(n,o){return function(n,r,i,a){t.initOptionalProperties(n,o),e(r),r.attr("tabindex","-1")}}return{template:function(e,t){return n},restrict:"E",controller:"MdContactChipsCtrl",controllerAs:"$mdContactChipsCtrl",bindToController:!0,compile:o,scope:{contactQuery:"&mdContacts",placeholder:"@",secondaryPlaceholder:"@",contactName:"@mdContactName",contactImage:"@mdContactImage",contactEmail:"@mdContactEmail",contacts:"=ngModel",requireMatch:"=?mdRequireMatch"}}}t.module("material.components.chips").directive("mdContactChips",e);var n=' <md-chips class="md-contact-chips" ng-model="$mdContactChipsCtrl.contacts" md-require-match="$mdContactChipsCtrl.requireMatch" md-autocomplete-snap> <md-autocomplete md-menu-class="md-contact-chips-suggestions" md-selected-item="$mdContactChipsCtrl.selectedItem" md-search-text="$mdContactChipsCtrl.searchText" md-items="item in $mdContactChipsCtrl.queryContact($mdContactChipsCtrl.searchText)" md-item-text="$mdContactChipsCtrl.mdContactName" md-no-cache="true" md-autoselect placeholder="{{$mdContactChipsCtrl.contacts.length == 0 ? $mdContactChipsCtrl.placeholder : $mdContactChipsCtrl.secondaryPlaceholder}}"> <div class="md-contact-suggestion"> <img ng-src="{{item[$mdContactChipsCtrl.contactImage]}}" alt="{{item[$mdContactChipsCtrl.contactName]}}" /> <span class="md-contact-name" md-highlight-text="$mdContactChipsCtrl.searchText"> {{item[$mdContactChipsCtrl.contactName]}} </span> <span class="md-contact-email" >{{item[$mdContactChipsCtrl.contactEmail]}}</span> </div> </md-autocomplete> <md-chip-template> <div class="md-contact-avatar"> <img ng-src="{{$chip[$mdContactChipsCtrl.contactImage]}}" alt="{{$chip[$mdContactChipsCtrl.contactName]}}" /> </div> <div class="md-contact-name"> {{$chip[$mdContactChipsCtrl.contactName]}} </div> </md-chip-template> </md-chips>';e.$inject=["$mdTheming","$mdUtil"]}(),function(){function e(){function e(e,n,o,r){if(r){var i=n.parent()[0].getElementsByTagName("md-tab"),a=Array.prototype.indexOf.call(i,n[0]),d=n.find("md-tab-body").eq(0).remove(),c=n.find("md-tab-label").eq(0).remove(),l=r.insertTab({scope:e,parent:e.$parent,index:a,element:n,template:d.html(),label:c.html()},a);e.select=e.select||t.noop,e.deselect=e.deselect||t.noop,e.$watch("active",function(e){e&&r.select(l.getIndex())}),e.$watch("disabled",function(){r.refreshIndex()}),e.$watch(function(){return Array.prototype.indexOf.call(i,n[0])},function(e){l.index=e,r.updateTabOrder()}),e.$on("$destroy",function(){r.removeTab(l)})}}return{require:"^?mdTabs",terminal:!0,compile:function(n,o){var r=n.find("md-tab-label"),i=n.find("md-tab-body");if(0==r.length&&(r=t.element("<md-tab-label></md-tab-label>"),o.label?r.text(o.label):r.append(n.contents())),0==i.length){var a=n.contents().detach();i=t.element("<md-tab-body></md-tab-body>"),i.append(a)}return n.append(r),i.html()&&n.append(i),e},scope:{active:"=?mdActive",disabled:"=?ngDisabled",select:"&?mdOnSelect",deselect:"&?mdOnDeselect"}}}t.module("material.components.tabs").directive("mdTab",e)}(),function(){function e(){return{require:"^?mdTabs",link:function(e,t,n,o){o&&o.attachRipple(e,t)}}}t.module("material.components.tabs").directive("mdTabItem",e)}(),function(){function e(){return{terminal:!0}}t.module("material.components.tabs").directive("mdTabLabel",e)}(),function(){function e(e){return{restrict:"A",compile:function(t,n){var o=e(n.mdTabScroll,null,!0);return function(e,t){t.on("mousewheel",function(t){e.$apply(function(){o(e,{$event:t})})})}}}}t.module("material.components.tabs").directive("mdTabScroll",e),e.$inject=["$parse"]}(),function(){function e(e,n,o,r,i,a,d,c,l,s){function m(){ie.selectedIndex=ie.selectedIndex||0,u(),f(),p(),s(n),a.nextTick(function(){ee(),X(),te(),ie.tabs[ie.selectedIndex]&&ie.tabs[ie.selectedIndex].scope.select(),se=!0,V()})}function u(){var e=c.$mdTabsTemplate,n=t.element(de.data);n.html(e),l(n.contents())(ie.parent),delete c.$mdTabsTemplate}function p(){t.element(o).on("resize",S),e.$on("$destroy",g)}function f(){e.$watch("$mdTabsCtrl.selectedIndex",y)}function h(e,t){var n=c.$normalize("md-"+e);t&&U(e,t),c.$observe(n,function(t){ie[e]=t})}function b(e,t){function n(t){ie[e]="false"Line truncated
}()}(window,window.angular);
+679
View File
@@ -0,0 +1,679 @@
/**
* @license AngularJS v1.3.17
* (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {'use strict';
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Any commits to this file should be reviewed with security in mind. *
* Changes to this file can potentially create security vulnerabilities. *
* An approval from 2 Core members with history of modifying *
* this file is required. *
* *
* Does the change somehow allow for arbitrary javascript to be executed? *
* Or allows for someone to change the prototype of built-in objects? *
* Or gives undesired access to variables likes document or window? *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
var $sanitizeMinErr = angular.$$minErr('$sanitize');
/**
* @ngdoc module
* @name ngSanitize
* @description
*
* # ngSanitize
*
* The `ngSanitize` module provides functionality to sanitize HTML.
*
*
* <div doc-module-components="ngSanitize"></div>
*
* See {@link ngSanitize.$sanitize `$sanitize`} for usage.
*/
/*
* HTML Parser By Misko Hevery (misko@hevery.com)
* based on: HTML Parser By John Resig (ejohn.org)
* Original code by Erik Arvidsson, Mozilla Public License
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
*
* // Use like so:
* htmlParser(htmlString, {
* start: function(tag, attrs, unary) {},
* end: function(tag) {},
* chars: function(text) {},
* comment: function(text) {}
* });
*
*/
/**
* @ngdoc service
* @name $sanitize
* @kind function
*
* @description
* The input is sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are
* then serialized back to properly escaped html string. This means that no unsafe input can make
* it into the returned string, however, since our parser is more strict than a typical browser
* parser, it's possible that some obscure input, which would be recognized as valid HTML by a
* browser, won't make it through the sanitizer. The input may also contain SVG markup.
* The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
* `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
*
* @param {string} html HTML input.
* @returns {string} Sanitized HTML.
*
* @example
<example module="sanitizeExample" deps="angular-sanitize.js">
<file name="index.html">
<script>
angular.module('sanitizeExample', ['ngSanitize'])
.controller('ExampleController', ['$scope', '$sce', function($scope, $sce) {
$scope.snippet =
'<p style="color:blue">an html\n' +
'<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
'snippet</p>';
$scope.deliberatelyTrustDangerousSnippet = function() {
return $sce.trustAsHtml($scope.snippet);
};
}]);
</script>
<div ng-controller="ExampleController">
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
<table>
<tr>
<td>Directive</td>
<td>How</td>
<td>Source</td>
<td>Rendered</td>
</tr>
<tr id="bind-html-with-sanitize">
<td>ng-bind-html</td>
<td>Automatically uses $sanitize</td>
<td><pre>&lt;div ng-bind-html="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
<td><div ng-bind-html="snippet"></div></td>
</tr>
<tr id="bind-html-with-trust">
<td>ng-bind-html</td>
<td>Bypass $sanitize by explicitly trusting the dangerous value</td>
<td>
<pre>&lt;div ng-bind-html="deliberatelyTrustDangerousSnippet()"&gt;
&lt;/div&gt;</pre>
</td>
<td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td>
</tr>
<tr id="bind-default">
<td>ng-bind</td>
<td>Automatically escapes</td>
<td><pre>&lt;div ng-bind="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
<td><div ng-bind="snippet"></div></td>
</tr>
</table>
</div>
</file>
<file name="protractor.js" type="protractor">
it('should sanitize the html snippet by default', function() {
expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
});
it('should inline raw snippet if bound to a trusted value', function() {
expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).
toBe("<p style=\"color:blue\">an html\n" +
"<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
"snippet</p>");
});
it('should escape snippet without any filter', function() {
expect(element(by.css('#bind-default div')).getInnerHtml()).
toBe("&lt;p style=\"color:blue\"&gt;an html\n" +
"&lt;em onmouseover=\"this.textContent='PWN3D!'\"&gt;click here&lt;/em&gt;\n" +
"snippet&lt;/p&gt;");
});
it('should update', function() {
element(by.model('snippet')).clear();
element(by.model('snippet')).sendKeys('new <b onclick="alert(1)">text</b>');
expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
toBe('new <b>text</b>');
expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe(
'new <b onclick="alert(1)">text</b>');
expect(element(by.css('#bind-default div')).getInnerHtml()).toBe(
"new &lt;b onclick=\"alert(1)\"&gt;text&lt;/b&gt;");
});
</file>
</example>
*/
function $SanitizeProvider() {
this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
return function(html) {
var buf = [];
htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
return !/^unsafe/.test($$sanitizeUri(uri, isImage));
}));
return buf.join('');
};
}];
}
function sanitizeText(chars) {
var buf = [];
var writer = htmlSanitizeWriter(buf, angular.noop);
writer.chars(chars);
return buf.join('');
}
// Regular Expressions for parsing tags and attributes
var START_TAG_REGEXP =
/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,
END_TAG_REGEXP = /^<\/\s*([\w:-]+)[^>]*>/,
ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
BEGIN_TAG_REGEXP = /^</,
BEGING_END_TAGE_REGEXP = /^<\//,
COMMENT_REGEXP = /<!--(.*?)-->/g,
DOCTYPE_REGEXP = /<!DOCTYPE([^>]*?)>/i,
CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
// Match everything outside of normal chars and " (quote character)
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
// Good source of info about elements and attributes
// http://dev.w3.org/html5/spec/Overview.html#semantics
// http://simon.html5.org/html-elements
// Safe Void Elements - HTML5
// http://dev.w3.org/html5/spec/Overview.html#void-elements
var voidElements = makeMap("area,br,col,hr,img,wbr");
// Elements that you can, intentionally, leave open (and which close themselves)
// http://dev.w3.org/html5/spec/Overview.html#optional-tags
var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
optionalEndTagInlineElements = makeMap("rp,rt"),
optionalEndTagElements = angular.extend({},
optionalEndTagInlineElements,
optionalEndTagBlockElements);
// Safe Block Elements - HTML5
var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
"aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
"h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
// Inline Elements - HTML5
var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
"bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
"samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
// SVG Elements
// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
var svgElements = makeMap("animate,animateColor,animateMotion,animateTransform,circle,defs," +
"desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,hkern,image,linearGradient," +
"line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,radialGradient,rect,set," +
"stop,svg,switch,text,title,tspan,use");
// Special Elements (can contain anything)
var specialElements = makeMap("script,style");
var validElements = angular.extend({},
voidElements,
blockElements,
inlineElements,
optionalEndTagElements,
svgElements);
//Attributes that have href and hence need to be sanitized
var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap,xlink:href");
var htmlAttrs = makeMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
'scope,scrolling,shape,size,span,start,summary,target,title,type,' +
'valign,value,vspace,width');
// SVG attributes (without "id" and "name" attributes)
// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
var svgAttrs = makeMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
'attributeName,attributeType,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,' +
'color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,' +
'font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,' +
'gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,' +
'keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,' +
'markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,' +
'overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,' +
'repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,' +
'stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,' +
'stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,' +
'stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,' +
'underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,' +
'viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,' +
'xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,' +
'zoomAndPan');
var validAttrs = angular.extend({},
uriAttrs,
svgAttrs,
htmlAttrs);
function makeMap(str) {
var obj = {}, items = str.split(','), i;
for (i = 0; i < items.length; i++) obj[items[i]] = true;
return obj;
}
/**
* @example
* htmlParser(htmlString, {
* start: function(tag, attrs, unary) {},
* end: function(tag) {},
* chars: function(text) {},
* comment: function(text) {}
* });
*
* @param {string} html string
* @param {object} handler
*/
function htmlParser(html, handler) {
if (typeof html !== 'string') {
if (html === null || typeof html === 'undefined') {
html = '';
} else {
html = '' + html;
}
}
var index, chars, match, stack = [], last = html, text;
stack.last = function() { return stack[stack.length - 1]; };
while (html) {
text = '';
chars = true;
// Make sure we're not in a script or style element
if (!stack.last() || !specialElements[stack.last()]) {
// Comment
if (html.indexOf("<!--") === 0) {
// comments containing -- are not allowed unless they terminate the comment
index = html.indexOf("--", 4);
if (index >= 0 && html.lastIndexOf("-->", index) === index) {
if (handler.comment) handler.comment(html.substring(4, index));
html = html.substring(index + 3);
chars = false;
}
// DOCTYPE
} else if (DOCTYPE_REGEXP.test(html)) {
match = html.match(DOCTYPE_REGEXP);
if (match) {
html = html.replace(match[0], '');
chars = false;
}
// end tag
} else if (BEGING_END_TAGE_REGEXP.test(html)) {
match = html.match(END_TAG_REGEXP);
if (match) {
html = html.substring(match[0].length);
match[0].replace(END_TAG_REGEXP, parseEndTag);
chars = false;
}
// start tag
} else if (BEGIN_TAG_REGEXP.test(html)) {
match = html.match(START_TAG_REGEXP);
if (match) {
// We only have a valid start-tag if there is a '>'.
if (match[4]) {
html = html.substring(match[0].length);
match[0].replace(START_TAG_REGEXP, parseStartTag);
}
chars = false;
} else {
// no ending tag found --- this piece should be encoded as an entity.
text += '<';
html = html.substring(1);
}
}
if (chars) {
index = html.indexOf("<");
text += index < 0 ? html : html.substring(0, index);
html = index < 0 ? "" : html.substring(index);
if (handler.chars) handler.chars(decodeEntities(text));
}
} else {
// IE versions 9 and 10 do not understand the regex '[^]', so using a workaround with [\W\w].
html = html.replace(new RegExp("([\\W\\w]*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'),
function(all, text) {
text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1");
if (handler.chars) handler.chars(decodeEntities(text));
return "";
});
parseEndTag("", stack.last());
}
if (html == last) {
throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " +
"of html: {0}", html);
}
last = html;
}
// Clean up any remaining tags
parseEndTag();
function parseStartTag(tag, tagName, rest, unary) {
tagName = angular.lowercase(tagName);
if (blockElements[tagName]) {
while (stack.last() && inlineElements[stack.last()]) {
parseEndTag("", stack.last());
}
}
if (optionalEndTagElements[tagName] && stack.last() == tagName) {
parseEndTag("", tagName);
}
unary = voidElements[tagName] || !!unary;
if (!unary)
stack.push(tagName);
var attrs = {};
rest.replace(ATTR_REGEXP,
function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
var value = doubleQuotedValue
|| singleQuotedValue
|| unquotedValue
|| '';
attrs[name] = decodeEntities(value);
});
if (handler.start) handler.start(tagName, attrs, unary);
}
function parseEndTag(tag, tagName) {
var pos = 0, i;
tagName = angular.lowercase(tagName);
if (tagName)
// Find the closest opened tag of the same type
for (pos = stack.length - 1; pos >= 0; pos--)
if (stack[pos] == tagName)
break;
if (pos >= 0) {
// Close all the open elements, up the stack
for (i = stack.length - 1; i >= pos; i--)
if (handler.end) handler.end(stack[i]);
// Remove the open elements from the stack
stack.length = pos;
}
}
}
var hiddenPre=document.createElement("pre");
/**
* decodes all entities into regular string
* @param value
* @returns {string} A string with decoded entities.
*/
function decodeEntities(value) {
if (!value) { return ''; }
hiddenPre.innerHTML = value.replace(/</g,"&lt;");
// innerText depends on styling as it doesn't display hidden elements.
// Therefore, it's better to use textContent not to cause unnecessary reflows.
return hiddenPre.textContent;
}
/**
* Escapes all potentially dangerous characters, so that the
* resulting string can be safely inserted into attribute or
* element text.
* @param value
* @returns {string} escaped text
*/
function encodeEntities(value) {
return value.
replace(/&/g, '&amp;').
replace(SURROGATE_PAIR_REGEXP, function(value) {
var hi = value.charCodeAt(0);
var low = value.charCodeAt(1);
return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
}).
replace(NON_ALPHANUMERIC_REGEXP, function(value) {
return '&#' + value.charCodeAt(0) + ';';
}).
replace(/</g, '&lt;').
replace(/>/g, '&gt;');
}
/**
* create an HTML/XML writer which writes to buffer
* @param {Array} buf use buf.jain('') to get out sanitized html string
* @returns {object} in the form of {
* start: function(tag, attrs, unary) {},
* end: function(tag) {},
* chars: function(text) {},
* comment: function(text) {}
* }
*/
function htmlSanitizeWriter(buf, uriValidator) {
var ignore = false;
var out = angular.bind(buf, buf.push);
return {
start: function(tag, attrs, unary) {
tag = angular.lowercase(tag);
if (!ignore && specialElements[tag]) {
ignore = tag;
}
if (!ignore && validElements[tag] === true) {
out('<');
out(tag);
angular.forEach(attrs, function(value, key) {
var lkey=angular.lowercase(key);
var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
if (validAttrs[lkey] === true &&
(uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
out(' ');
out(key);
out('="');
out(encodeEntities(value));
out('"');
}
});
out(unary ? '/>' : '>');
}
},
end: function(tag) {
tag = angular.lowercase(tag);
if (!ignore && validElements[tag] === true) {
out('</');
out(tag);
out('>');
}
if (tag == ignore) {
ignore = false;
}
},
chars: function(chars) {
if (!ignore) {
out(encodeEntities(chars));
}
}
};
}
// define ngSanitize module and register $sanitize service
angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
/* global sanitizeText: false */
/**
* @ngdoc filter
* @name linky
* @kind function
*
* @description
* Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
* plain email address links.
*
* Requires the {@link ngSanitize `ngSanitize`} module to be installed.
*
* @param {string} text Input text.
* @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
* @returns {string} Html-linkified text.
*
* @usage
<span ng-bind-html="linky_expression | linky"></span>
*
* @example
<example module="linkyExample" deps="angular-sanitize.js">
<file name="index.html">
<script>
angular.module('linkyExample', ['ngSanitize'])
.controller('ExampleController', ['$scope', function($scope) {
$scope.snippet =
'Pretty text with some links:\n'+
'http://angularjs.org/,\n'+
'mailto:us@somewhere.org,\n'+
'another@somewhere.org,\n'+
'and one more: ftp://127.0.0.1/.';
$scope.snippetWithTarget = 'http://angularjs.org/';
}]);
</script>
<div ng-controller="ExampleController">
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
<table>
<tr>
<td>Filter</td>
<td>Source</td>
<td>Rendered</td>
</tr>
<tr id="linky-filter">
<td>linky filter</td>
<td>
<pre>&lt;div ng-bind-html="snippet | linky"&gt;<br>&lt;/div&gt;</pre>
</td>
<td>
<div ng-bind-html="snippet | linky"></div>
</td>
</tr>
<tr id="linky-target">
<td>linky target</td>
<td>
<pre>&lt;div ng-bind-html="snippetWithTarget | linky:'_blank'"&gt;<br>&lt;/div&gt;</pre>
</td>
<td>
<div ng-bind-html="snippetWithTarget | linky:'_blank'"></div>
</td>
</tr>
<tr id="escaped-html">
<td>no filter</td>
<td><pre>&lt;div ng-bind="snippet"&gt;<br>&lt;/div&gt;</pre></td>
<td><div ng-bind="snippet"></div></td>
</tr>
</table>
</file>
<file name="protractor.js" type="protractor">
it('should linkify the snippet with urls', function() {
expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
'another@somewhere.org, and one more: ftp://127.0.0.1/.');
expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
});
it('should not linkify snippet without the linky filter', function() {
expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
'another@somewhere.org, and one more: ftp://127.0.0.1/.');
expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
});
it('should update', function() {
element(by.model('snippet')).clear();
element(by.model('snippet')).sendKeys('new http://link.');
expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
toBe('new http://link.');
expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
.toBe('new http://link.');
});
it('should work with the target property', function() {
expect(element(by.id('linky-target')).
element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
toBe('http://angularjs.org/');
expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
});
</file>
</example>
*/
angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
var LINKY_URL_REGEXP =
/((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"”’]/i,
MAILTO_REGEXP = /^mailto:/i;
return function(text, target) {
if (!text) return text;
var match;
var raw = text;
var html = [];
var url;
var i;
while ((match = raw.match(LINKY_URL_REGEXP))) {
// We can not end in these as they are sometimes found at the end of the sentence
url = match[0];
// if we did not match ftp/http/www/mailto then assume mailto
if (!match[2] && !match[4]) {
url = (match[3] ? 'http://' : 'mailto:') + url;
}
i = match.index;
addText(raw.substr(0, i));
addLink(url, match[0].replace(MAILTO_REGEXP, ''));
raw = raw.substring(i + match[0].length);
}
addText(raw);
return $sanitize(html.join(''));
function addText(text) {
if (!text) {
return;
}
html.push(sanitizeText(text));
}
function addLink(url, text) {
html.push('<a ');
if (angular.isDefined(target)) {
html.push('target="',
target,
'" ');
}
html.push('href="',
url.replace(/"/g, '&quot;'),
'">');
addText(text);
html.push('</a>');
}
};
}]);
})(window, window.angular);
+16
View File
@@ -0,0 +1,16 @@
/*
AngularJS v1.3.17
(c) 2010-2014 Google, Inc. http://angularjs.org
License: MIT
*/
(function(n,h,p){'use strict';function E(a){var e=[];r(e,h.noop).chars(a);return e.join("")}function g(a){var e={};a=a.split(",");var d;for(d=0;d<a.length;d++)e[a[d]]=!0;return e}function F(a,e){function d(a,b,d,l){b=h.lowercase(b);if(s[b])for(;f.last()&&t[f.last()];)c("",f.last());u[b]&&f.last()==b&&c("",b);(l=v[b]||!!l)||f.push(b);var m={};d.replace(G,function(a,b,e,c,d){m[b]=q(e||c||d||"")});e.start&&e.start(b,m,l)}function c(a,b){var c=0,d;if(b=h.lowercase(b))for(c=f.length-1;0<=c&&f[c]!=b;c--);
if(0<=c){for(d=f.length-1;d>=c;d--)e.end&&e.end(f[d]);f.length=c}}"string"!==typeof a&&(a=null===a||"undefined"===typeof a?"":""+a);var b,k,f=[],m=a,l;for(f.last=function(){return f[f.length-1]};a;){l="";k=!0;if(f.last()&&w[f.last()])a=a.replace(new RegExp("([\\W\\w]*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(a,b){b=b.replace(H,"$1").replace(I,"$1");e.chars&&e.chars(q(b));return""}),c("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(e.comment&&
e.comment(a.substring(4,b)),a=a.substring(b+3),k=!1);else if(x.test(a)){if(b=a.match(x))a=a.replace(b[0],""),k=!1}else if(J.test(a)){if(b=a.match(y))a=a.substring(b[0].length),b[0].replace(y,c),k=!1}else K.test(a)&&((b=a.match(z))?(b[4]&&(a=a.substring(b[0].length),b[0].replace(z,d)),k=!1):(l+="<",a=a.substring(1)));k&&(b=a.indexOf("<"),l+=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),e.chars&&e.chars(q(l)))}if(a==m)throw L("badparse",a);m=a}c()}function q(a){if(!a)return"";A.innerHTML=a.replace(/</g,
"&lt;");return A.textContent}function B(a){return a.replace(/&/g,"&amp;").replace(M,function(a){var d=a.charCodeAt(0);a=a.charCodeAt(1);return"&#"+(1024*(d-55296)+(a-56320)+65536)+";"}).replace(N,function(a){return"&#"+a.charCodeAt(0)+";"}).replace(/</g,"&lt;").replace(/>/g,"&gt;")}function r(a,e){var d=!1,c=h.bind(a,a.push);return{start:function(a,k,f){a=h.lowercase(a);!d&&w[a]&&(d=a);d||!0!==C[a]||(c("<"),c(a),h.forEach(k,function(d,f){var k=h.lowercase(f),g="img"===a&&"src"===k||"background"===
k;!0!==O[k]||!0===D[k]&&!e(d,g)||(c(" "),c(f),c('="'),c(B(d)),c('"'))}),c(f?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==C[a]||(c("</"),c(a),c(">"));a==d&&(d=!1)},chars:function(a){d||c(B(a))}}}var L=h.$$minErr("$sanitize"),z=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,y=/^<\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^</,J=/^<\//,H=/\x3c!--(.*?)--\x3e/g,x=/<!DOCTYPE([^>]*?)>/i,
I=/<!\[CDATA\[(.*?)]]\x3e/g,M=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,N=/([^\#-~| |!])/g,v=g("area,br,col,hr,img,wbr");n=g("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr");p=g("rp,rt");var u=h.extend({},p,n),s=h.extend({},n,g("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")),t=h.extend({},p,g("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
n=g("animate,animateColor,animateMotion,animateTransform,circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,radialGradient,rect,set,stop,svg,switch,text,title,tspan,use");var w=g("script,style"),C=h.extend({},v,s,t,u,n),D=g("background,cite,href,longdesc,src,usemap,xlink:href");n=g("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,size,span,start,summary,target,title,type,valign,value,vspace,width");
p=g("accent-height,accumulate,additive,alphabetic,arabic-form,ascent,attributeName,attributeType,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan");
var O=h.extend({},D,p,n),A=document.createElement("pre");h.module("ngSanitize",[]).provider("$sanitize",function(){this.$get=["$$sanitizeUri",function(a){return function(e){var d=[];F(e,r(d,function(c,b){return!/^unsafe/.test(a(c,b))}));return d.join("")}}]});h.module("ngSanitize").filter("linky",["$sanitize",function(a){var e=/((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,d=/^mailto:/i;return function(c,b){function k(a){a&&g.push(E(a))}function f(a,c){g.push("<a ");
h.isDefined(b)&&g.push('target="',b,'" ');g.push('href="',a.replace(/"/g,"&quot;"),'">');k(c);g.push("</a>")}if(!c)return c;for(var m,l=c,g=[],n,p;m=l.match(e);)n=m[0],m[2]||m[4]||(n=(m[3]?"http://":"mailto:")+n),p=m.index,k(l.substr(0,p)),f(n,m[0].replace(d,"")),l=l.substring(p+m[0].length);k(l);return a(g.join(""))}}])})(window,window.angular);
//# sourceMappingURL=angular-sanitize.min.js.map
@@ -0,0 +1,8 @@
{
"version":3,
"file":"angular-sanitize.min.js",
"lineCount":15,
"mappings":"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 truncated
"sources":["angular-sanitize.js"],
"names":["window","angular","undefined","sanitizeText","chars","buf","htmlSanitizeWriter","writer","noop","join","makeMap","str","obj","items","split","i","length","htmlParser","html","handler","parseStartTag","tag","tagName","rest","unary","lowercase","blockElements","stack","last","inlineElements","parseEndTag","optionalEndTagElements","voidElements","push","attrs","replace","ATTR_REGEXP","match","name","doubleQuotedValue","singleQuotedValue","unquotedValue","decodeEntities","start","pos","end","index","text","stack.last","specialElements","RegExp","all","COMMENT_REGEXP","CDATA_REGEXP","indexOf","lastIndexOf","comment","substring","DOCTYPE_REGEXP","test","BEGING_END_TAGE_REGEXP","END_TAG_REGEXP","BEGIN_TAG_REGEXP","START_TAG_REGEXP","$sanitizeMinErr","value","hiddenPre","innerHTML","textContent","encodeEntities","SURROGATE_PAIR_REGEXP","hi","charCodeAt","low","NON_ALPHANUMERIC_REGEXP","uriValidator","ignore","out","bind","validElements","forEach","key","lkey","isImage","validAttrs","uriAttrs","$$minErr","optionalEndTagBlockElements","optionalEndTagInlineElements","extend","svgElements","htmlAttrs","svgAttrs","document","createElement","module","provider","$SanitizeProvider","$get","$$sanitizeUri","uri","filter","$sanitize","LINKY_URL_REGEXP","MAILTO_REGEXP","target","addText","addLink","url","isDefined","raw","substr"]
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,7 @@
/**
* State-based routing for AngularJS
* @version v0.2.15
* @link http://angular-ui.github.com/
* @license MIT License, http://www.opensource.org/licenses/MIT
*/
"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(a,b,c){"use strict";function d(a,b){return N(new(N(function(){},{prototype:a})),b)}function e(a){return M(arguments,function(b){b!==a&&M(b,function(b,c){a.hasOwnProperty(c)||(a[c]=b)})}),a}function f(a,b){var c=[];for(var d in a.path){if(a.path[d]!==b.path[d])break;c.push(a.path[d])}return c}function g(a){if(Object.keys)return Object.keys(a);var b=[];return M(a,function(a,c){b.push(c)}),b}function h(a,b){if(Array.prototype.indexOf)return a.indexOf(b,Number(arguments[2])||0);var c=a.length>>>0,d=Number(arguments[2])||0;for(d=0>d?Math.ceil(d):Math.floor(d),0>d&&(d+=c);c>d;d++)if(d in a&&a[d]===b)return d;return-1}function i(a,b,c,d){var e,i=f(c,d),j={},k=[];for(var l in i)if(i[l].params&&(e=g(i[l].params),e.length))for(var m in e)h(k,e[m])>=0||(k.push(e[m]),j[e[m]]=a[e[m]]);return N({},j,b)}function j(a,b,c){if(!c){c=[];for(var d in a)c.push(d)}for(var e=0;e<c.length;e++){var f=c[e];if(a[f]!=b[f])return!1}return!0}function k(a,b){var c={};return M(a,function(a){c[a]=b[a]}),c}function l(a){var b={},c=Array.prototype.concat.apply(Array.prototype,Array.prototype.slice.call(arguments,1));return M(c,function(c){c in a&&(b[c]=a[c])}),b}function m(a){var b={},c=Array.prototype.concat.apply(Array.prototype,Array.prototype.slice.call(arguments,1));for(var d in a)-1==h(c,d)&&(b[d]=a[d]);return b}function n(a,b){var c=L(a),d=c?[]:{};return M(a,function(a,e){b(a,e)&&(d[c?d.length:e]=a)}),d}function o(a,b){var c=L(a)?[]:{};return M(a,function(a,d){c[d]=b(a,d)}),c}function p(a,b){var d=1,f=2,i={},j=[],k=i,l=N(a.when(i),{$$promises:i,$$values:i});this.study=function(i){function n(a,c){if(s[c]!==f){if(r.push(c),s[c]===d)throw r.splice(0,h(r,c)),new Error("Cyclic dependency: "+r.join(" -> "));if(s[c]=d,J(a))q.push(c,[function(){return b.get(a)}],j);else{var e=b.annotate(a);M(e,function(a){a!==c&&i.hasOwnProperty(a)&&n(i[a],a)}),q.push(c,a,e)}r.pop(),s[c]=f}}function o(a){return K(a)&&a.then&&a.$$promises}if(!K(i))throw new Error("'invocables' must be an object");var p=g(i||{}),q=[],r=[],s={};return M(i,n),i=r=s=null,function(d,f,g){function h(){--u||(v||e(t,f.$$values),r.$$values=t,r.$$promises=r.$$promises||!0,delete r.$$inheritedValues,n.resolve(t))}function i(a){r.$$failure=a,n.reject(a)}function j(c,e,f){function j(a){l.reject(a),i(a)}function k(){if(!H(r.$$failure))try{l.resolve(b.invoke(e,g,t)),l.promise.then(function(a){t[c]=a,h()},j)}catch(a){j(a)}}var l=a.defer(),m=0;M(f,function(a){s.hasOwnProperty(a)&&!d.hasOwnProperty(a)&&(m++,s[a].then(function(b){t[a]=b,--m||k()},j))}),m||k(),s[c]=l.promise}if(o(d)&&g===c&&(g=f,f=d,d=null),d){if(!K(d))throw new Error("'locals' must be an object")}else d=k;if(f){if(!o(f))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else f=l;var n=a.defer(),r=n.promise,s=r.$$promises={},t=N({},d),u=1+q.length/3,v=!1;if(H(f.$$failure))return i(f.$$failure),r;f.$$inheritedValues&&e(t,m(f.$$inheritedValues,p)),N(s,f.$$promises),f.$$values?(v=e(t,m(f.$$values,p)),r.$$inheritedValues=m(f.$$values,p),h()):(f.$$inheritedValues&&(r.$$inheritedValues=m(f.$$inheritedValues,p)),f.then(h,i));for(var w=0,x=q.length;x>w;w+=3)d.hasOwnProperty(q[w])?h():j(q[w],q[w+1],q[w+2]);return r}},this.resolve=function(a,b,c,d){return this.study(a)(b,c,d)}}function q(a,b,c){this.fromConfig=function(a,b,c){return H(a.template)?this.fromString(a.template,b):H(a.templateUrl)?this.fromUrl(a.templateUrl,b):H(a.templateProvider)?this.fromProvider(a.templateProvider,b,c):null},this.fromString=function(a,b){return I(a)?a(b):a},this.fromUrl=function(c,d){return I(c)&&(c=c(d)),null==c?null:a.get(c,{cache:b,headers:{Accept:"text/html"}}).then(function(a){return a.data})},this.fromProvider=function(a,b,d){return c.invoke(a,null,d||{params:b})}}function r(a,b,e){function f(b,c,d,e){if(q.push(b),o[b])return o[b];if(!/^\w+(-+\w+)*(?:\[\])?$/.test(b))throw new Error("Invalid parameter name '"+b+"' in pattern '"+a+"'");if(p[b])throw new Error("Duplicate parameter name '"+b+"' in pattern '"+a+"'");return p[b]=new P.Param(b,c,d,e),p[b]}function g(a,b,c,d){var e=["",""],f=a.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&");if(!b)return f;switch(c){case!1:e=["(",")"+(d?"?":"")];break;case!0:e=["?(",")?"];break;default:e=["("+c+"|",")?"]}return f+e[0]+b+e[1]}function h(e,f){var g,h,i,j,k;return g=e[2]||e[3],k=b.params[g],i=a.substring(m,e.index),h=f?e[4]:e[4]||("*"==e[1]?".*":null),j=P.type(h||"string")||d(P.type("string"),{pattern:new RegExp(h,b.caseInsensitive?"i":c)}),{id:g,regexp:h,segment:i,type:j,cfg:k}}b=N({params:{}},K(b)?b:{});var i,j=/([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,k=/([:]?)([\w\[\]-]+)|\{([\w\[\]-]+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,l="^",m=0,n=this.segments=[],o=e?e.params:{},p=this.params=e?e.params.$$new():new P.ParamSet,q=[];this.source=a;for(var r,s,t;(i=j.exec(a))&&(r=h(i,!1),!(r.segment.indexOf("?")>=0));)s=f(r.id,r.Line truncated
File diff suppressed because it is too large. Load diff
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff. Show more