Skip to content
This repository has been archived by the owner on May 4, 2022. It is now read-only.

Commit

Permalink
Merge pull request #679 from apetro/page-title-takes-string
Browse files Browse the repository at this point in the history
Reflect page title in document title
  • Loading branch information
apetro authored Feb 1, 2018
2 parents 077fd08 + 9590884 commit 0d55055
Show file tree
Hide file tree
Showing 10 changed files with 459 additions and 28 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Added

+ `mainService` now offers `computeWindowTitle(...)` (#679)
+ `AppHeaderOptionsController` now offers `updateWindowTitle(...)` (#679)

### Changed

+ `app-header` (and so, `frame-page`) now set Document title (#679)

### Fixed

+ Label widget cover dismiss button as "OK" rather than "Continue" (#675)
Expand Down
27 changes: 25 additions & 2 deletions components/portal/main/controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,29 @@ define(['angular', 'require'], function(angular, require) {
layoutMode: 'list', // other option is 'widgets
};

/**
* Set Document title.
* Asks mainService what the document title ought to be and
* sets the document title to that value.
* @param {string} [pageTitle] - Name of specific page viewed.
*/
function updateWindowTitle(pageTitle) {
var appTitle = NAMES.title;

var portalTitle = '';
if ($rootScope.portal && $rootScope.portal.theme &&
$rootScope.portal.theme.title) {
// there's an active theme with a title.
// consider that title the name of the portal
portalTitle = $rootScope.portal.theme.title;
}

var windowTitle =
mainService.computeWindowTitle(pageTitle, appTitle, portalTitle);

$document[0].title = windowTitle;
}

// =====functions ======
var init = function() {
$scope.$storage = $localStorage.$default(defaults);
Expand All @@ -44,13 +67,13 @@ define(['angular', 'require'], function(angular, require) {
$scope.APP_OPTIONS = APP_OPTIONS;

if (NAMES.title) {
mainService.setTitle();
updateWindowTitle();
}
// https://github.com/Gillespie59/eslint-plugin-angular/issues/231
// eslint-disable-next-line angular/on-watch
$rootScope.$watch('portal.theme', function(newValue, oldValue) {
if (newValue && newValue !== oldValue) {
mainService.setTitle();
updateWindowTitle();
}
});

Expand Down
222 changes: 222 additions & 0 deletions components/portal/main/main_service_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
/*
* Licensed to Apereo under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Apereo licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at the following location:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
'use strict';
/* eslint-env node */
/* global inject */
define(['angular-mocks', 'portal'], function() {
describe('mainService', function() {
var service;

var loginSilentUrl;
var httpBackend;

beforeEach(function() {
module('portal');
});

beforeEach(inject(function(
_mainService_, _$httpBackend_,
SERVICE_LOC, MESSAGES, APP_FLAGS
) {
service = _mainService_;
httpBackend = _$httpBackend_;
loginSilentUrl = APP_FLAGS.loginOnLoad;

if (loginSilentUrl) {
httpBackend.whenGET(loginSilentUrl)
.respond({'status': 'success', 'username': 'admin'});
}

httpBackend.whenGET(SERVICE_LOC.sessionInfo).respond();
}));

it('should set title to include page, app, and portal name when '
+ 'all of these are present and non-redundant.', function() {
// setup
var pageTitle = 'Timesheets';
var appTitle = 'STAR Time Entry';
var portalTitle = 'MyUW';

// test
var windowTitle =
service.computeWindowTitle(pageTitle, appTitle, portalTitle);

expect(windowTitle)
.toEqual('Timesheets | STAR Time Entry | MyUW');

httpBackend.flush();
});

it('should set title to omit app name when redundant with portal name',
function() {
// setup
var pageTitle = 'Notifications';
var appTitle = 'MyUW';
var portalTitle = 'MyUW';

// test
var windowTitle =
service.computeWindowTitle(pageTitle, appTitle, portalTitle);

expect(windowTitle).toEqual('Notifications | MyUW');

httpBackend.flush();
});

it('should set title to omit app name when null', function() {
// setup
var pageTitle = 'Notifications';
var appTitle = null;
var portalTitle = 'MyUW';

// test
var windowTitle =
service.computeWindowTitle(pageTitle, appTitle, portalTitle);

expect(windowTitle).toEqual('Notifications | MyUW');

httpBackend.flush();
});

it('should set title to omit app name when it is empty', function() {
// setup
var pageTitle = 'Notifications';
var appTitle = '';
var portalTitle = 'MyUW';

// test
var windowTitle =
service.computeWindowTitle(pageTitle, appTitle, portalTitle);

expect(windowTitle).toEqual('Notifications | MyUW');

httpBackend.flush();
});

it('should set title to omit page name when it is null',
function() {
// setup
var appTitle = 'STAR Time Entry';
var portalTitle = 'MyUW';

// test
var windowTitle =
service.computeWindowTitle(null, appTitle, portalTitle);

expect(windowTitle).toEqual('STAR Time Entry | MyUW');

httpBackend.flush();
});

it('should set title to omit page name when it is empty string',
function() {
// setup
var pageTitle = '';
var appTitle = 'STAR Time Entry';
var portalTitle = 'MyUW';

// test
var windowTitle =
service.computeWindowTitle(pageTitle, appTitle, portalTitle);

expect(windowTitle).toEqual('STAR Time Entry | MyUW');

httpBackend.flush();
});

it('should set title to only the portal name when the app name is '
+ 'redundant and the page name is not provided.', function() {
// setup
var pageTitle = '';
var appTitle = 'MyUW';
var portalTitle = 'MyUW';

// test
var windowTitle =
service.computeWindowTitle(pageTitle, appTitle, portalTitle);

expect(windowTitle).toEqual('MyUW');

httpBackend.flush();
});

it('should set title to only the portal name when redundant with both '
+ 'the app name and the page name.', function() {
// setup
var pageTitle = 'MyUW';
var appTitle = 'MyUW';
var portalTitle = 'MyUW';

// test
var windowTitle =
service.computeWindowTitle(pageTitle, appTitle, portalTitle);

expect(windowTitle).toEqual('MyUW');

httpBackend.flush();
});

it('should set title to only the app name when portal name and page '
+ 'name are null', function() {
// setup
var pageTitle = null;
var appTitle = 'STAR Time and Leave';
var portalTitle = null;

// test
var windowTitle =
service.computeWindowTitle(pageTitle, appTitle, portalTitle);

expect(windowTitle).toEqual('STAR Time and Leave');

httpBackend.flush();
});

it('should set title to only the page name when portal name and app '
+ 'name are null', function() {
// setup
var pageTitle = 'SomePage';
var appTitle = null;
var portalTitle = null;

// test
var windowTitle =
service.computeWindowTitle(pageTitle, appTitle, portalTitle);

expect(windowTitle).toEqual('SomePage');

httpBackend.flush();
});

it('should gracefully handle missing theme.', function() {
// setup
var pageTitle = 'SomePage';
var appTitle = 'SomeApp';
var portalTitle = null;

// test
var windowTitle =
service.computeWindowTitle(pageTitle, appTitle, portalTitle);

expect(windowTitle).toEqual('SomePage | SomeApp');

httpBackend.flush();
});
});
});
77 changes: 61 additions & 16 deletions components/portal/main/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ define(['angular'], function(angular) {

.factory('mainService', [
'$http', '$log', '$sessionStorage',
'miscService', 'SERVICE_LOC', 'APP_FLAGS', '$rootScope', 'NAMES',
'$document',
'miscService', 'SERVICE_LOC', 'APP_FLAGS', 'NAMES',
function($http, $log, $sessionStorage,
miscService, SERVICE_LOC, APP_FLAGS, $rootScope, NAMES,
$document) {
miscService, SERVICE_LOC, APP_FLAGS, NAMES) {
var prom = $http.get(SERVICE_LOC.sessionInfo, {cache: true});
var userPromise;

Expand Down Expand Up @@ -74,26 +72,73 @@ define(['angular'], function(angular) {
}

/**
* set the frame title using theme
* Compute the window title
*
* Returns
* page-title | app-title | portal-title (in an application), or
* page-title | portal-title (if the app has same name as the portal), or
* app-title | portal-title (if page name unknown or redundant)
* portal-title (if page name unknown or redundant and app name redundant)
*
* Examples:
* "Timesheets | STAR Time Entry | MyUW" ,
* for the Timesheets page in an app named "STAR Time Entry" in
* a portal named "MyUW", or
*
* "Notifications | MyUW",
* for the notifications page in an app named "MyUW" in
* a portal named "MyUW".
*
* "STAR Time Entry | MyUW"
* in an app named "STAR Time Entry" in a portal named "MyUW"
* when the page name is unspecified.
*
* "MyUW"
* in an app named "MyUW" in a portal named "MyUW"
* when the page name is unspecified.
*/
function setTitle() {
var frameTitle = '';
if ($rootScope.portal && $rootScope.portal.theme) {
frameTitle = $rootScope.portal.theme.title;
if (frameTitle !== NAMES.title && !APP_FLAGS.isWeb) {
frameTitle = ' | ' + frameTitle;
} else {
// since frame title equals the title in NAMES lets not duplicate it
frameTitle = '';
function computeWindowTitle(pageTitle, appTitle, portalTitle) {
var windowTitle = ''; // we finally set the window title to this.

// assemble the window title from the gathered pieces,
// starting from the end of the window title and working back to the
// beginning.

// if the portal has a name, end the window title with that
// (if the portal lacks a name, portalTitle is still empty string)

if (portalTitle) {
windowTitle = portalTitle;
}

// if the app name differs from the portal, prepend it.
// if it's the same name, omit it to avoid silly redundancy like
// "MyUW | MyUW"
if (appTitle && appTitle !== portalTitle) {
// if the windowTitle already has content, first add a separator
if (windowTitle) {
windowTitle = ' | ' + windowTitle;
}
windowTitle = appTitle + windowTitle;
}
$document[0].title = NAMES.title + frameTitle;

// if there's a page name not redundant with the app name, prepend it.
if (pageTitle && pageTitle !== '' && pageTitle !== appTitle) {
// if the windowTitle already has content, first add a separator
if (windowTitle !== '') {
windowTitle = ' | ' + windowTitle;
}
windowTitle = pageTitle + windowTitle;
}

// finally, return the built up windowTitle
return windowTitle;
}

return {
getUser: getUser,
isGuest: isGuest,
setTitle: setTitle,
computeWindowTitle: computeWindowTitle,
};
}]);
});
Loading

0 comments on commit 0d55055

Please sign in to comment.