diff --git a/docs/src/guide/index.md b/docs/src/guide/index.md index f6d22fb2fb..93cb95bb7a 100644 --- a/docs/src/guide/index.md +++ b/docs/src/guide/index.md @@ -910,7 +910,24 @@ A capability's implementation may also expose a static method `appliesTo(model)` which should return a boolean value, and will be used by the platform to filter down capabilities to those which should be exposed by specific domain objects, based on their domain object models. - + +## Containers Category + +Containers provide options for the `mct-container` directive. + +The definition for an extension in the `containers` category should include: + +* `key`: An identifier for the container. +* `template`: An Angular template for the container, including an + `ng-transclude` where contained content should go. +* `attributes`: An array of attribute names. The values associated with + these attributes will be exposed in the template's scope under the + name provided by the `alias` property. +* `alias`: The property name in scope under which attributes will be + exposed. Optional; defaults to "container". + +Note that `templateUrl` is not supported for `containers`. + ## Controls Category Controls provide options for the `mct-control` directive. diff --git a/karma.conf.js b/karma.conf.js index cee8401576..e63b6712ef 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -39,6 +39,7 @@ module.exports = function(config) { {pattern: 'example/**/*.js', included: false}, {pattern: 'platform/**/*.js', included: false}, {pattern: 'warp/**/*.js', included: false}, + {pattern: 'platform/**/*.html', included: false}, 'test-main.js' ], diff --git a/platform/commonUI/about/bundle.js b/platform/commonUI/about/bundle.js index 90235af297..aff0825f5c 100644 --- a/platform/commonUI/about/bundle.js +++ b/platform/commonUI/about/bundle.js @@ -26,12 +26,26 @@ define([ "./src/LogoController", "./src/AboutController", "./src/LicenseController", + "text!./res/templates/app-logo.html", + "text!./res/templates/about-logo.html", + "text!./res/templates/overlay-about.html", + "text!./res/templates/license-apache.html", + "text!./res/templates/license-mit.html", + "text!./res/templates/licenses.html", + "text!./res/templates/licenses-export-md.html", 'legacyRegistry' ], function ( aboutDialogTemplate, LogoController, AboutController, LicenseController, + appLogoTemplate, + aboutLogoTemplate, + overlayAboutTemplate, + licenseApacheTemplate, + licenseMitTemplate, + licensesTemplate, + licensesExportMdTemplate, legacyRegistry ) { "use strict"; @@ -43,12 +57,12 @@ define([ { "key": "app-logo", "priority": "optional", - "templateUrl": "templates/app-logo.html" + "template": appLogoTemplate }, { "key": "about-logo", "priority": "preferred", - "templateUrl": "templates/about-logo.html" + "template": aboutLogoTemplate }, { "key": "about-dialog", @@ -56,15 +70,15 @@ define([ }, { "key": "overlay-about", - "templateUrl": "templates/overlay-about.html" + "template": overlayAboutTemplate }, { "key": "license-apache", - "templateUrl": "templates/license-apache.html" + "template": licenseApacheTemplate }, { "key": "license-mit", - "templateUrl": "templates/license-mit.html" + "template": licenseMitTemplate } ], "controllers": [ @@ -156,11 +170,11 @@ define([ "routes": [ { "when": "/licenses", - "templateUrl": "templates/licenses.html" + "template": licensesTemplate }, { "when": "/licenses-md", - "templateUrl": "templates/licenses-export-md.html" + "template": licensesExportMdTemplate } ] } diff --git a/platform/commonUI/browse/bundle.js b/platform/commonUI/browse/bundle.js index 10eb6c7004..74c4059cab 100644 --- a/platform/commonUI/browse/bundle.js +++ b/platform/commonUI/browse/bundle.js @@ -37,6 +37,16 @@ define([ "./src/creation/AddActionProvider", "./src/creation/CreationService", "./src/windowing/WindowTitler", + "text!./res/templates/browse.html", + "text!./res/templates/create/locator.html", + "text!./res/templates/browse-object.html", + "text!./res/templates/create/create-button.html", + "text!./res/templates/create/create-menu.html", + "text!./res/templates/items/grid-item.html", + "text!./res/templates/browse/object-header.html", + "text!./res/templates/menu-arrow.html", + "text!./res/templates/back-arrow.html", + "text!./res/templates/items/items.html", 'legacyRegistry' ], function ( BrowseController, @@ -54,6 +64,16 @@ define([ AddActionProvider, CreationService, WindowTitler, + browseTemplate, + locatorTemplate, + browseObjectTemplate, + createButtonTemplate, + createMenuTemplate, + gridItemTemplate, + objectHeaderTemplate, + menuArrowTemplate, + backArrowTemplate, + itemsTemplate, legacyRegistry ) { "use strict"; @@ -63,12 +83,12 @@ define([ "routes": [ { "when": "/browse/:ids*", - "templateUrl": "templates/browse.html", + "template": browseTemplate, "reloadOnSearch": false }, { "when": "", - "templateUrl": "templates/browse.html", + "template": browseTemplate, "reloadOnSearch": false } ], @@ -134,13 +154,13 @@ define([ "controls": [ { "key": "locator", - "templateUrl": "templates/create/locator.html" + "template": locatorTemplate } ], "representations": [ { "key": "browse-object", - "templateUrl": "templates/browse-object.html", + "template": browseObjectTemplate, "gestures": [ "drop" ], @@ -150,18 +170,18 @@ define([ }, { "key": "create-button", - "templateUrl": "templates/create/create-button.html" + "template": createButtonTemplate }, { "key": "create-menu", - "templateUrl": "templates/create/create-menu.html", + "template": createMenuTemplate, "uses": [ "action" ] }, { "key": "grid-item", - "templateUrl": "templates/items/grid-item.html", + "template": gridItemTemplate, "uses": [ "type", "action", @@ -174,14 +194,14 @@ define([ }, { "key": "object-header", - "templateUrl": "templates/browse/object-header.html", + "template": objectHeaderTemplate, "uses": [ "type" ] }, { "key": "menu-arrow", - "templateUrl": "templates/menu-arrow.html", + "template": menuArrowTemplate, "uses": [ "action" ], @@ -194,7 +214,7 @@ define([ "uses": [ "context" ], - "templateUrl": "templates/back-arrow.html" + "template": backArrowTemplate } ], "services": [ @@ -250,7 +270,7 @@ define([ "name": "Items", "glyph": "9", "description": "Grid of available items", - "templateUrl": "templates/items/items.html", + "template": itemsTemplate, "uses": [ "composition" ], diff --git a/platform/commonUI/dialog/bundle.js b/platform/commonUI/dialog/bundle.js index 3839afbcf8..3d99408478 100644 --- a/platform/commonUI/dialog/bundle.js +++ b/platform/commonUI/dialog/bundle.js @@ -24,10 +24,24 @@ define([ "./src/DialogService", "./src/OverlayService", + "text!./res/templates/overlay-dialog.html", + "text!./res/templates/overlay-options.html", + "text!./res/templates/dialog.html", + "text!./res/templates/overlay-blocking-message.html", + "text!./res/templates/message.html", + "text!./res/templates/overlay-message-list.html", + "text!./res/templates/overlay.html", 'legacyRegistry' ], function ( DialogService, OverlayService, + overlayDialogTemplate, + overlayOptionsTemplate, + dialogTemplate, + overlayBlockingMessageTemplate, + messageTemplate, + overlayMessageListTemplate, + overlayTemplate, legacyRegistry ) { "use strict"; @@ -57,33 +71,33 @@ define([ "templates": [ { "key": "overlay-dialog", - "templateUrl": "templates/overlay-dialog.html" + "template": overlayDialogTemplate }, { "key": "overlay-options", - "templateUrl": "templates/overlay-options.html" + "template": overlayOptionsTemplate }, { "key": "form-dialog", - "templateUrl": "templates/dialog.html" + "template": dialogTemplate }, { "key": "overlay-blocking-message", - "templateUrl": "templates/overlay-blocking-message.html" + "template": overlayBlockingMessageTemplate }, { "key": "message", - "templateUrl": "templates/message.html" + "template": messageTemplate }, { "key": "overlay-message-list", - "templateUrl": "templates/overlay-message-list.html" + "template": overlayMessageListTemplate } ], "containers": [ { "key": "overlay", - "templateUrl": "templates/overlay.html" + "template": overlayTemplate } ] } diff --git a/platform/commonUI/edit/bundle.js b/platform/commonUI/edit/bundle.js index f5142031e6..c4b0da1798 100644 --- a/platform/commonUI/edit/bundle.js +++ b/platform/commonUI/edit/bundle.js @@ -36,6 +36,12 @@ define([ "./src/policies/EditActionPolicy", "./src/representers/EditRepresenter", "./src/representers/EditToolbarRepresenter", + "text!./res/templates/edit.html", + "text!./res/templates/library.html", + "text!./res/templates/edit-object.html", + "text!./res/templates/edit-action-buttons.html", + "text!./res/templates/elements.html", + "text!./res/templates/topbar-edit.html", 'legacyRegistry' ], function ( EditController, @@ -52,6 +58,12 @@ define([ EditActionPolicy, EditRepresenter, EditToolbarRepresenter, + editTemplate, + libraryTemplate, + editObjectTemplate, + editActionButtonsTemplate, + elementsTemplate, + topbarEditTemplate, legacyRegistry ) { "use strict"; @@ -61,7 +73,7 @@ define([ "routes": [ { "when": "/edit", - "templateUrl": "templates/edit.html" + "template": editTemplate } ], "controllers": [ @@ -185,27 +197,27 @@ define([ "templates": [ { "key": "edit-library", - "templateUrl": "templates/library.html" + "template": libraryTemplate } ], "representations": [ { "key": "edit-object", - "templateUrl": "templates/edit-object.html", + "template": editObjectTemplate, "uses": [ "view" ] }, { "key": "edit-action-buttons", - "templateUrl": "templates/edit-action-buttons.html", + "template": editActionButtonsTemplate, "uses": [ "action" ] }, { "key": "edit-elements", - "templateUrl": "templates/elements.html", + "template": elementsTemplate, "uses": [ "composition" ], @@ -215,7 +227,7 @@ define([ }, { "key": "topbar-edit", - "templateUrl": "templates/topbar-edit.html" + "template": topbarEditTemplate } ], "representers": [ diff --git a/platform/commonUI/general/bundle.js b/platform/commonUI/general/bundle.js index 07978cef35..f3d6d98f61 100644 --- a/platform/commonUI/general/bundle.js +++ b/platform/commonUI/general/bundle.js @@ -49,6 +49,25 @@ define([ "./src/directives/MCTScroll", "./src/directives/MCTSplitPane", "./src/directives/MCTSplitter", + "text!./res/templates/bottombar.html", + "text!./res/templates/controls/action-button.html", + "text!./res/templates/controls/input-filter.html", + "text!./res/templates/indicator.html", + "text!./res/templates/message-banner.html", + "text!./res/templates/progress-bar.html", + "text!./res/templates/controls/time-controller.html", + "text!./res/templates/containers/accordion.html", + "text!./res/templates/subtree.html", + "text!./res/templates/tree.html", + "text!./res/templates/tree-node.html", + "text!./res/templates/label.html", + "text!./res/templates/controls/action-group.html", + "text!./res/templates/menu/context-menu.html", + "text!./res/templates/controls/switcher.html", + "text!./res/templates/object-inspector.html", + "text!./res/templates/controls/selector.html", + "text!./res/templates/controls/datetime-picker.html", + "text!./res/templates/controls/datetime-field.html", 'legacyRegistry' ], function ( UrlService, @@ -78,6 +97,25 @@ define([ MCTScroll, MCTSplitPane, MCTSplitter, + bottombarTemplate, + actionButtonTemplate, + inputFilterTemplate, + indicatorTemplate, + messageBannerTemplate, + progressBarTemplate, + timeControllerTemplate, + accordionTemplate, + subtreeTemplate, + treeTemplate, + treeNodeTemplate, + labelTemplate, + actionGroupTemplate, + contextMenuTemplate, + switcherTemplate, + objectInspectorTemplate, + selectorTemplate, + datetimePickerTemplate, + datetimeFieldTemplate, legacyRegistry ) { "use strict"; @@ -146,31 +184,31 @@ define([ "templates": [ { "key": "bottombar", - "templateUrl": "templates/bottombar.html" + "template": bottombarTemplate }, { "key": "action-button", - "templateUrl": "templates/controls/action-button.html" + "template": actionButtonTemplate }, { "key": "input-filter", - "templateUrl": "templates/controls/input-filter.html" + "template": inputFilterTemplate }, { "key": "indicator", - "templateUrl": "templates/indicator.html" + "template": indicatorTemplate }, { "key": "message-banner", - "templateUrl": "templates/message-banner.html" + "template": messageBannerTemplate }, { "key": "progress-bar", - "templateUrl": "templates/progress-bar.html" + "template": progressBarTemplate }, { "key": "time-controller", - "templateUrl": "templates/controls/time-controller.html" + "template": timeControllerTemplate } ], "controllers": [ @@ -379,7 +417,7 @@ define([ "containers": [ { "key": "accordion", - "templateUrl": "templates/containers/accordion.html", + "template": accordionTemplate, "attributes": [ "label" ] @@ -388,7 +426,7 @@ define([ "representations": [ { "key": "tree", - "templateUrl": "templates/subtree.html", + "template": subtreeTemplate, "uses": [ "composition" ], @@ -397,25 +435,25 @@ define([ }, { "key": "tree", - "templateUrl": "templates/tree.html" + "template": treeTemplate }, { "key": "subtree", - "templateUrl": "templates/subtree.html", + "template": subtreeTemplate, "uses": [ "composition" ] }, { "key": "tree-node", - "templateUrl": "templates/tree-node.html", + "template": treeNodeTemplate, "uses": [ "action" ] }, { "key": "label", - "templateUrl": "templates/label.html", + "template": labelTemplate, "uses": [ "type", "location" @@ -428,7 +466,7 @@ define([ }, { "key": "node", - "templateUrl": "templates/label.html", + "template": labelTemplate, "uses": [ "type" ], @@ -439,42 +477,42 @@ define([ }, { "key": "action-group", - "templateUrl": "templates/controls/action-group.html", + "template": actionGroupTemplate, "uses": [ "action" ] }, { "key": "context-menu", - "templateUrl": "templates/menu/context-menu.html", + "template": contextMenuTemplate, "uses": [ "action" ] }, { "key": "switcher", - "templateUrl": "templates/controls/switcher.html", + "template": switcherTemplate, "uses": [ "view" ] }, { "key": "object-inspector", - "templateUrl": "templates/object-inspector.html" + "template": objectInspectorTemplate } ], "controls": [ { "key": "selector", - "templateUrl": "templates/controls/selector.html" + "template": selectorTemplate }, { "key": "datetime-picker", - "templateUrl": "templates/controls/datetime-picker.html" + "template": datetimePickerTemplate }, { "key": "datetime-field", - "templateUrl": "templates/controls/datetime-field.html" + "template": datetimeFieldTemplate } ], "licenses": [ diff --git a/platform/commonUI/general/src/directives/MCTContainer.js b/platform/commonUI/general/src/directives/MCTContainer.js index f65cf0803d..e35c52f9f6 100644 --- a/platform/commonUI/general/src/directives/MCTContainer.js +++ b/platform/commonUI/general/src/directives/MCTContainer.js @@ -47,13 +47,7 @@ define( // Initialize container map from extensions containers.forEach(function (container) { - var key = container.key; - containerMap[key] = Object.create(container); - containerMap[key].templateUrl = [ - container.bundle.path, - container.bundle.resources, - container.templateUrl - ].join("/"); + containerMap[container.key] = container; }); return { @@ -85,13 +79,11 @@ define( scope[alias] = copiedAttributes; }, - // Get the template URL for this container, based - // on its attributes. - templateUrl: function (element, attrs) { - var key = attrs.key; - return containerMap[key].templateUrl; + template: function (element, attrs) { + var key = attrs.key, + container = containerMap[key]; + return container ? container.template : ""; } - }; } diff --git a/platform/commonUI/general/test/directives/MCTContainerSpec.js b/platform/commonUI/general/test/directives/MCTContainerSpec.js index 2d0ce444da..0c25e6c645 100644 --- a/platform/commonUI/general/test/directives/MCTContainerSpec.js +++ b/platform/commonUI/general/test/directives/MCTContainerSpec.js @@ -30,12 +30,12 @@ define( var testContainers = [ { bundle: { path: "a", resources: "b" }, - templateUrl: "c/template.html", + template: "
foo
", key: "abc" }, { bundle: { path: "x", resources: "y" }, - templateUrl: "z/template.html", + template: "bar", key: "xyz", attributes: [ "someAttr", "someOtherAttr" ] } @@ -55,15 +55,15 @@ define( }); it("chooses a template based on key", function () { - expect(mctContainer.templateUrl( + expect(mctContainer.template( undefined, { key: "abc" } - )).toEqual("a/b/c/template.html"); + )).toEqual(testContainers[0].template); - expect(mctContainer.templateUrl( + expect(mctContainer.template( undefined, { key: "xyz" } - )).toEqual("x/y/z/template.html"); + )).toEqual(testContainers[1].template); }); it("copies attributes needed by the container", function () { diff --git a/platform/commonUI/inspect/bundle.js b/platform/commonUI/inspect/bundle.js index ea2f58e432..9576a344c1 100644 --- a/platform/commonUI/inspect/bundle.js +++ b/platform/commonUI/inspect/bundle.js @@ -25,11 +25,19 @@ define([ "./src/gestures/InfoGesture", "./src/gestures/InfoButtonGesture", "./src/services/InfoService", + "text!./res/info-table.html", + "text!./res/info-bubble.html", + "text!./res/bubble.html", + "text!./res/templates/info-button.html", 'legacyRegistry' ], function ( InfoGesture, InfoButtonGesture, InfoService, + infoTableTemplate, + infoBubbleTemplate, + bubbleTemplate, + infoButtonTemplate, legacyRegistry ) { "use strict"; @@ -39,17 +47,17 @@ define([ "templates": [ { "key": "info-table", - "templateUrl": "info-table.html" + "template": infoTableTemplate }, { "key": "info-bubble", - "templateUrl": "info-bubble.html" + "template": infoBubbleTemplate } ], "containers": [ { "key": "bubble", - "templateUrl": "bubble.html", + "template": bubbleTemplate, "attributes": [ "bubbleTitle", "bubbleLayout" @@ -99,7 +107,7 @@ define([ "representations": [ { "key": "info-button", - "templateUrl": "templates/info-button.html", + "template": infoButtonTemplate, "gestures": [ "infobutton" ] diff --git a/platform/commonUI/notification/bundle.js b/platform/commonUI/notification/bundle.js index a9123847fc..4bde1dff03 100644 --- a/platform/commonUI/notification/bundle.js +++ b/platform/commonUI/notification/bundle.js @@ -25,11 +25,13 @@ define([ "./src/NotificationIndicatorController", "./src/NotificationIndicator", "./src/NotificationService", + "text!./res/notification-indicator.html", 'legacyRegistry' ], function ( NotificationIndicatorController, NotificationIndicator, NotificationService, + notificationIndicatorTemplate, legacyRegistry ) { "use strict"; @@ -53,7 +55,7 @@ define([ "templates": [ { "key": "notificationIndicatorTemplate", - "templateUrl": "notification-indicator.html" + "template": notificationIndicatorTemplate } ], "controllers": [ diff --git a/platform/features/clock/bundle.js b/platform/features/clock/bundle.js index b7661e418b..1d22a3f8a0 100644 --- a/platform/features/clock/bundle.js +++ b/platform/features/clock/bundle.js @@ -29,6 +29,8 @@ define([ "./src/controllers/RefreshingController", "./src/actions/StartTimerAction", "./src/actions/RestartTimerAction", + "text!./res/templates/clock.html", + "text!./res/templates/timer.html", 'legacyRegistry' ], function ( ClockIndicator, @@ -38,6 +40,8 @@ define([ RefreshingController, StartTimerAction, RestartTimerAction, + clockTemplate, + timerTemplate, legacyRegistry ) { "use strict"; @@ -116,13 +120,13 @@ define([ "key": "clock", "type": "clock", "editable": false, - "templateUrl": "templates/clock.html" + "template": clockTemplate }, { "key": "timer", "type": "timer", "editable": false, - "templateUrl": "templates/timer.html" + "template": timerTemplate } ], "actions": [ diff --git a/platform/features/conductor/bundle.js b/platform/features/conductor/bundle.js index 1a215e2a10..9987be5c68 100644 --- a/platform/features/conductor/bundle.js +++ b/platform/features/conductor/bundle.js @@ -25,11 +25,13 @@ define([ "./src/ConductorRepresenter", "./src/ConductorTelemetryDecorator", "./src/ConductorService", + "text!./res/templates/time-conductor.html", 'legacyRegistry' ], function ( ConductorRepresenter, ConductorTelemetryDecorator, ConductorService, + timeConductorTemplate, legacyRegistry ) { "use strict"; @@ -70,7 +72,7 @@ define([ "templates": [ { "key": "time-conductor", - "templateUrl": "templates/time-conductor.html" + "template": timeConductorTemplate } ], "constants": [ diff --git a/platform/features/events/bundle.js b/platform/features/events/bundle.js index 829036acb3..f494784eff 100644 --- a/platform/features/events/bundle.js +++ b/platform/features/events/bundle.js @@ -25,11 +25,13 @@ define([ "./src/EventListController", "./src/directives/MCTDataTable", "./src/policies/MessagesViewPolicy", + "text!./res/templates/messages.html", 'legacyRegistry' ], function ( EventListController, MCTDataTable, MessagesViewPolicy, + messagesTemplate, legacyRegistry ) { "use strict"; @@ -44,7 +46,7 @@ define([ "name": "Messages", "glyph": "5", "description": "Scrolling list of messages.", - "templateUrl": "templates/messages.html", + "template": messagesTemplate, "needs": [ "telemetry" ], diff --git a/platform/features/events/src/directives/MCTDataTable.js b/platform/features/events/src/directives/MCTDataTable.js index e830fbe885..0ea0946fe8 100644 --- a/platform/features/events/src/directives/MCTDataTable.js +++ b/platform/features/events/src/directives/MCTDataTable.js @@ -25,14 +25,14 @@ * Module defining MCTDataTable. Created by shale on 06/22/2015. */ define( - [], - function () { + ['text!../../res/templates/mct-data-table.html'], + function (dataTableTemplate) { "use strict"; function MCTDataTable($window) { return { restrict: "E", - templateUrl: "platform/features/events/res/templates/mct-data-table.html", + template: dataTableTemplate, scope: { headers: "=", rows: "=", diff --git a/platform/features/imagery/bundle.js b/platform/features/imagery/bundle.js index 79c3d00994..e17534fc4c 100644 --- a/platform/features/imagery/bundle.js +++ b/platform/features/imagery/bundle.js @@ -25,11 +25,13 @@ define([ "./src/policies/ImageryViewPolicy", "./src/controllers/ImageryController", "./src/directives/MCTBackgroundImage", + "text!./res/templates/imagery.html", 'legacyRegistry' ], function ( ImageryViewPolicy, ImageryController, MCTBackgroundImage, + imageryTemplate, legacyRegistry ) { "use strict"; @@ -42,7 +44,7 @@ define([ "name": "Imagery", "key": "imagery", "glyph": "ã", - "templateUrl": "templates/imagery.html", + "template": imageryTemplate, "priority": "preferred", "needs": [ "telemetry" diff --git a/platform/features/layout/bundle.js b/platform/features/layout/bundle.js index 538d456007..493a910b97 100644 --- a/platform/features/layout/bundle.js +++ b/platform/features/layout/bundle.js @@ -25,11 +25,27 @@ define([ "./src/LayoutController", "./src/FixedController", "./src/LayoutCompositionPolicy", + "text!./res/templates/layout.html", + "text!./res/templates/fixed.html", + "text!./res/templates/frame.html", + "text!./res/templates/elements/telemetry.html", + "text!./res/templates/elements/box.html", + "text!./res/templates/elements/line.html", + "text!./res/templates/elements/text.html", + "text!./res/templates/elements/image.html", 'legacyRegistry' ], function ( LayoutController, FixedController, LayoutCompositionPolicy, + layoutTemplate, + fixedTemplate, + frameTemplate, + telemetryTemplate, + boxTemplate, + lineTemplate, + textTemplate, + imageTemplate, legacyRegistry ) { "use strict"; @@ -44,7 +60,7 @@ define([ "name": "Display Layout", "glyph": "L", "type": "layout", - "templateUrl": "templates/layout.html", + "template": layoutTemplate, "editable": true, "uses": [] }, @@ -53,7 +69,7 @@ define([ "name": "Fixed Position", "glyph": "3", "type": "telemetry.panel", - "templateUrl": "templates/fixed.html", + "template": fixedTemplate, "uses": [ "composition" ], @@ -191,7 +207,7 @@ define([ "representations": [ { "key": "frame", - "templateUrl": "templates/frame.html" + "template": frameTemplate } ], "controllers": [ @@ -218,23 +234,23 @@ define([ "templates": [ { "key": "fixed.telemetry", - "templateUrl": "templates/elements/telemetry.html" + "template": telemetryTemplate }, { "key": "fixed.box", - "templateUrl": "templates/elements/box.html" + "template": boxTemplate }, { "key": "fixed.line", - "templateUrl": "templates/elements/line.html" + "template": lineTemplate }, { "key": "fixed.text", - "templateUrl": "templates/elements/text.html" + "template": textTemplate }, { "key": "fixed.image", - "templateUrl": "templates/elements/image.html" + "template": imageTemplate } ], "policies": [ diff --git a/platform/features/layout/src/FixedController.js b/platform/features/layout/src/FixedController.js index 28ca9c3990..751a0e70d3 100644 --- a/platform/features/layout/src/FixedController.js +++ b/platform/features/layout/src/FixedController.js @@ -303,12 +303,16 @@ define( this.generateDragHandles = generateDragHandles; // Track current selection state - this.selection = $scope.selection; + $scope.$watch("selection", function (selection) { + this.selection = selection; - // Expose the view's selection proxy - if (this.selection) { - this.selection.proxy(new FixedProxy(addElement, $q, dialogService)); - } + // Expose the view's selection proxy + if (this.selection) { + this.selection.proxy( + new FixedProxy(addElement, $q, dialogService) + ); + } + }.bind(this)); // Refresh list of elements whenever model changes $scope.$watch("model.modified", refreshElements); diff --git a/platform/features/layout/test/FixedControllerSpec.js b/platform/features/layout/test/FixedControllerSpec.js index b6842497e0..7c545e2d3d 100644 --- a/platform/features/layout/test/FixedControllerSpec.js +++ b/platform/features/layout/test/FixedControllerSpec.js @@ -148,6 +148,8 @@ define( mockHandler, mockFormatter ); + + findWatch("selection")(mockScope.selection); }); it("subscribes when a domain object is available", function () { diff --git a/platform/features/pages/bundle.js b/platform/features/pages/bundle.js index 1d5cb24210..70119db5bd 100644 --- a/platform/features/pages/bundle.js +++ b/platform/features/pages/bundle.js @@ -23,9 +23,11 @@ define([ "./src/EmbeddedPageController", + "text!./res/iframe.html", 'legacyRegistry' ], function ( EmbeddedPageController, + iframeTemplate, legacyRegistry ) { "use strict"; @@ -54,7 +56,7 @@ define([ ], "views": [ { - "templateUrl": "iframe.html", + "template": iframeTemplate, "name": "Page", "type": "example.page", "key": "example.page", diff --git a/platform/features/plot/bundle.js b/platform/features/plot/bundle.js index 18eba3aa51..e780a61d2c 100644 --- a/platform/features/plot/bundle.js +++ b/platform/features/plot/bundle.js @@ -25,11 +25,13 @@ define([ "./src/MCTChart", "./src/PlotController", "./src/policies/PlotViewPolicy", + "text!./res/templates/plot.html", 'legacyRegistry' ], function ( MCTChart, PlotController, PlotViewPolicy, + plotTemplate, legacyRegistry ) { "use strict"; @@ -42,7 +44,7 @@ define([ "name": "Plot", "key": "plot", "glyph": "6", - "templateUrl": "templates/plot.html", + "template": plotTemplate, "needs": [ "telemetry" ], diff --git a/platform/features/rtevents/bundle.js b/platform/features/rtevents/bundle.js index 8efaf072bd..25142d7dc6 100644 --- a/platform/features/rtevents/bundle.js +++ b/platform/features/rtevents/bundle.js @@ -25,11 +25,13 @@ define([ "./src/RTEventListController", "./src/directives/MCTRTDataTable", "./src/policies/RTMessagesViewPolicy", + "text!./res/templates/rtmessages.html", 'legacyRegistry' ], function ( RTEventListController, MCTRTDataTable, RTMessagesViewPolicy, + rtmessagesTemplate, legacyRegistry ) { "use strict"; @@ -44,7 +46,7 @@ define([ "name": "RT Messages", "glyph": "5", "description": "Scrolling list of real time messages.", - "templateUrl": "templates/rtmessages.html", + "template": rtmessagesTemplate, "needs": [ "telemetry" ], diff --git a/platform/features/rtevents/src/directives/MCTRTDataTable.js b/platform/features/rtevents/src/directives/MCTRTDataTable.js index d7337eab4f..6f0cc38913 100644 --- a/platform/features/rtevents/src/directives/MCTRTDataTable.js +++ b/platform/features/rtevents/src/directives/MCTRTDataTable.js @@ -25,14 +25,14 @@ * Module defining MCTRTDataTable. Created by shale on 06/25/2015. */ define( - [], - function () { + ['text!../../res/templates/mct-rt-data-table.html'], + function (dataTableTemplate) { "use strict"; function MCTRTDataTable($window) { return { restrict: "E", - templateUrl: "platform/features/rtevents/res/templates/mct-rt-data-table.html", + template: dataTableTemplate, scope: { headers: "=", rows: "=", diff --git a/platform/features/rtscrolling/bundle.js b/platform/features/rtscrolling/bundle.js index d0b8f68f10..3466dc44f1 100644 --- a/platform/features/rtscrolling/bundle.js +++ b/platform/features/rtscrolling/bundle.js @@ -23,9 +23,11 @@ define([ "./src/RTScrollingListController", + "text!./res/templates/rtscrolling.html", 'legacyRegistry' ], function ( RTScrollingListController, + rtscrollingTemplate, legacyRegistry ) { "use strict"; @@ -40,7 +42,7 @@ define([ "name": "Scrolling", "glyph": "5", "description": "Scrolling list of data values.", - "templateUrl": "templates/rtscrolling.html", + "template": rtscrollingTemplate, "needs": [ "telemetry" ], diff --git a/platform/features/scrolling/bundle.js b/platform/features/scrolling/bundle.js index 546fb6a06b..567330e165 100644 --- a/platform/features/scrolling/bundle.js +++ b/platform/features/scrolling/bundle.js @@ -23,9 +23,11 @@ define([ "./src/ScrollingListController", + "text!./res/templates/scrolling.html", 'legacyRegistry' ], function ( ScrollingListController, + scrollingTemplate, legacyRegistry ) { "use strict"; @@ -40,7 +42,7 @@ define([ "name": "Scrolling", "glyph": "5", "description": "Scrolling list of data values.", - "templateUrl": "templates/scrolling.html", + "template": scrollingTemplate, "needs": [ "telemetry" ], diff --git a/platform/features/static-markup/bundle.js b/platform/features/static-markup/bundle.js index 63dfe3ac0b..4ac5a13701 100644 --- a/platform/features/static-markup/bundle.js +++ b/platform/features/static-markup/bundle.js @@ -23,9 +23,11 @@ define([ + "text!./res/markup.html", 'legacyRegistry' ], function ( + markupTemplate, legacyRegistry ) { "use strict"; @@ -45,7 +47,7 @@ define([ ], "views": [ { - "templateUrl": "markup.html", + "template": markupTemplate, "name": "Static Markup", "type": "static.markup", "key": "static.markup" diff --git a/platform/features/timeline/bundle.js b/platform/features/timeline/bundle.js index a791fc4fb0..5be95f643c 100644 --- a/platform/features/timeline/bundle.js +++ b/platform/features/timeline/bundle.js @@ -38,6 +38,16 @@ define([ "./src/directives/MCTSwimlaneDrop", "./src/directives/MCTSwimlaneDrag", "./src/services/ObjectLoader", + "text!./res/templates/values.html", + "text!./res/templates/timeline.html", + "text!./res/templates/activity-gantt.html", + "text!./res/templates/tabular-swimlane-cols-tree.html", + "text!./res/templates/tabular-swimlane-cols-data.html", + "text!./res/templates/resource-graphs.html", + "text!./res/templates/resource-graph-labels.html", + "text!./res/templates/legend-item.html", + "text!./res/templates/ticks.html", + "text!./res/templates/controls/datetime.html", 'legacyRegistry' ], function ( TimelineController, @@ -56,6 +66,16 @@ define([ MCTSwimlaneDrop, MCTSwimlaneDrag, ObjectLoader, + valuesTemplate, + timelineTemplate, + activityGanttTemplate, + tabularSwimlaneColsTreeTemplate, + tabularSwimlaneColsDataTemplate, + resourceGraphsTemplate, + resourceGraphLabelsTemplate, + legendItemTemplate, + ticksTemplate, + datetimeTemplate, legacyRegistry ) { "use strict"; @@ -226,7 +246,7 @@ define([ "key": "values", "name": "Values", "glyph": "A", - "templateUrl": "templates/values.html", + "template": valuesTemplate, "type": "mode", "uses": [ "cost" @@ -239,7 +259,7 @@ define([ "glyph": "S", "type": "timeline", "description": "A timeline view of Timelines and Activities.", - "templateUrl": "templates/timeline.html", + "template": timelineTemplate, "editable": true, "toolbar": { "sections": [ @@ -335,7 +355,7 @@ define([ "representations": [ { "key": "gantt", - "templateUrl": "templates/activity-gantt.html", + "template": activityGanttTemplate, "uses": [ "timespan", "type" @@ -346,42 +366,42 @@ define([ { "key": "timeline-tabular-swimlane-cols-tree", "priority": "mandatory", - "templateUrl": "templates/tabular-swimlane-cols-tree.html" + "template": tabularSwimlaneColsTreeTemplate }, { "key": "timeline-tabular-swimlane-cols-data", "priority": "mandatory", - "templateUrl": "templates/tabular-swimlane-cols-data.html" + "template": tabularSwimlaneColsDataTemplate }, { "key": "timeline-resource-graphs", "priority": "mandatory", - "templateUrl": "templates/resource-graphs.html" + "template": resourceGraphsTemplate }, { "key": "timeline-resource-graph-labels", "priority": "mandatory", - "templateUrl": "templates/resource-graph-labels.html" + "template": resourceGraphLabelsTemplate }, { "key": "timeline-legend-item", "priority": "mandatory", - "templateUrl": "templates/legend-item.html" + "template": legendItemTemplate }, { "key": "timeline-ticks", "priority": "mandatory", - "templateUrl": "templates/ticks.html" + "template": ticksTemplate } ], "controls": [ { "key": "timeline-datetime", - "templateUrl": "templates/controls/datetime.html" + "template": datetimeTemplate }, { "key": "duration", - "templateUrl": "templates/controls/datetime.html" + "template": datetimeTemplate } ], "controllers": [ diff --git a/platform/features/timeline/res/templates/activity-gantt.html b/platform/features/timeline/res/templates/activity-gantt.html index 2af4900dc9..69d1d8984a 100644 --- a/platform/features/timeline/res/templates/activity-gantt.html +++ b/platform/features/timeline/res/templates/activity-gantt.html @@ -22,10 +22,10 @@
+ } : {}">
diff --git a/platform/features/timeline/src/controllers/TimelineController.js b/platform/features/timeline/src/controllers/TimelineController.js index 8667bfec5f..a31fffa1c7 100644 --- a/platform/features/timeline/src/controllers/TimelineController.js +++ b/platform/features/timeline/src/controllers/TimelineController.js @@ -98,7 +98,7 @@ define( }); } } - + // Recalculate swimlane state on changes $scope.$watch("domainObject", swimlanePopulator.populate); @@ -108,6 +108,9 @@ define( // Carry over changes in swimlane set to changes in graphs $scope.$watch(graphMask, repopulateGraphs); + // Pass selection object into swimlane populator + $scope.$watch("selection", swimlanePopulator.selection); + // Convey current selection to drag handle populator $scope.$watch("selection.get()", dragPopulator.select); diff --git a/platform/features/timeline/src/controllers/swimlane/TimelineSwimlanePopulator.js b/platform/features/timeline/src/controllers/swimlane/TimelineSwimlanePopulator.js index a15d97196f..0875c87d5a 100644 --- a/platform/features/timeline/src/controllers/swimlane/TimelineSwimlanePopulator.js +++ b/platform/features/timeline/src/controllers/swimlane/TimelineSwimlanePopulator.js @@ -46,7 +46,8 @@ define( start = Number.POSITIVE_INFINITY, end = Number.NEGATIVE_INFINITY, colors = (configuration.colors || {}), - assigner = new TimelineColorAssigner(colors); + assigner = new TimelineColorAssigner(colors), + lastDomainObject; // Track extremes of start/end times function trackStartEnd(timespan) { @@ -144,12 +145,25 @@ define( domainObject && new TimelineProxy(domainObject, selection) ); } + + lastDomainObject = domainObject; + } + + function setSelectionObject(s) { + selection = s; + recalculateSwimlanes(lastDomainObject); } // Ensure colors are exposed in configuration configuration.colors = colors; return { + /** + * Set the selection object associated with this timeline view. + * @param {Object} selection the selection object + */ + selection: setSelectionObject, + /** * Update list of swimlanes to match those reachable from this * object. diff --git a/platform/features/timeline/test/controllers/swimlane/TimelineSwimlanePopulatorSpec.js b/platform/features/timeline/test/controllers/swimlane/TimelineSwimlanePopulatorSpec.js index 02b2010def..895ae34a79 100644 --- a/platform/features/timeline/test/controllers/swimlane/TimelineSwimlanePopulatorSpec.js +++ b/platform/features/timeline/test/controllers/swimlane/TimelineSwimlanePopulatorSpec.js @@ -150,6 +150,15 @@ define( expect(mockSelection.proxy).toHaveBeenCalled(); }); + it("allows selection object to be changed", function () { + var mockNewSelectionObject = jasmine.createSpyObj( + 'new-selection', + ['get', 'select', 'proxy'] + ); + populator.selection(mockNewSelectionObject); + expect(mockNewSelectionObject.proxy) + .toHaveBeenCalled(); + }); }); } diff --git a/platform/forms/bundle.js b/platform/forms/bundle.js index 43c76d18ae..19ebf4d9b5 100644 --- a/platform/forms/bundle.js +++ b/platform/forms/bundle.js @@ -29,6 +29,15 @@ define([ "./src/controllers/CompositeController", "./src/controllers/ColorController", "./src/controllers/DialogButtonController", + "text!./res/templates/controls/checkbox.html", + "text!./res/templates/controls/datetime.html", + "text!./res/templates/controls/select.html", + "text!./res/templates/controls/textfield.html", + "text!./res/templates/controls/button.html", + "text!./res/templates/controls/color.html", + "text!./res/templates/controls/composite.html", + "text!./res/templates/controls/menu-button.html", + "text!./res/templates/controls/dialog.html", 'legacyRegistry' ], function ( MCTForm, @@ -38,6 +47,15 @@ define([ CompositeController, ColorController, DialogButtonController, + checkboxTemplate, + datetimeTemplate, + selectTemplate, + textfieldTemplate, + buttonTemplate, + colorTemplate, + compositeTemplate, + menuButtonTemplate, + dialogTemplate, legacyRegistry ) { "use strict"; @@ -59,6 +77,7 @@ define([ "key": "mctControl", "implementation": MCTControl, "depends": [ + "templateLinker", "controls[]" ] } @@ -66,39 +85,39 @@ define([ "controls": [ { "key": "checkbox", - "templateUrl": "templates/controls/checkbox.html" + "template": checkboxTemplate }, { "key": "datetime", - "templateUrl": "templates/controls/datetime.html" + "template": datetimeTemplate }, { "key": "select", - "templateUrl": "templates/controls/select.html" + "template": selectTemplate }, { "key": "textfield", - "templateUrl": "templates/controls/textfield.html" + "template": textfieldTemplate }, { "key": "button", - "templateUrl": "templates/controls/button.html" + "template": buttonTemplate }, { "key": "color", - "templateUrl": "templates/controls/color.html" + "template": colorTemplate }, { "key": "composite", - "templateUrl": "templates/controls/composite.html" + "template": compositeTemplate }, { "key": "menu-button", - "templateUrl": "templates/controls/menu-button.html" + "template": menuButtonTemplate }, { "key": "dialog-button", - "templateUrl": "templates/controls/dialog.html" + "template": dialogTemplate } ], "controllers": [ diff --git a/platform/forms/src/MCTControl.js b/platform/forms/src/MCTControl.js index 78ac8c194d..09192a09ee 100644 --- a/platform/forms/src/MCTControl.js +++ b/platform/forms/src/MCTControl.js @@ -36,23 +36,18 @@ define( * @constructor * @memberof platform/forms */ - function MCTControl(controls) { + function MCTControl(templateLinker, controls) { var controlMap = {}; // Prepopulate controlMap for easy look up by key controls.forEach(function (control) { - var path = [ - control.bundle.path, - control.bundle.resources, - control.templateUrl - ].join("/"); - controlMap[control.key] = path; + controlMap[control.key] = control; }); function link(scope, element, attrs, ngModelController) { + var changeTemplate = templateLinker.link(scope, element); scope.$watch("key", function (key) { - // Pass the template URL to ng-include via scope. - scope.inclusion = controlMap[key]; + changeTemplate(controlMap[key]); }); scope.ngModelController = ngModelController; } @@ -61,10 +56,6 @@ define( // Only show at the element level restrict: "E", - // Use ng-include as a template; "inclusion" will be the real - // template path - template: '', - // ngOptions is terminal, so we need to be higher priority priority: 1000, diff --git a/platform/forms/src/MCTForm.js b/platform/forms/src/MCTForm.js index ce48ed1572..70c18cbf2f 100644 --- a/platform/forms/src/MCTForm.js +++ b/platform/forms/src/MCTForm.js @@ -27,8 +27,8 @@ * @namespace platform/forms */ define( - ["./controllers/FormController"], - function (FormController) { + ["./controllers/FormController", "text!../res/templates/form.html"], + function (FormController, formTemplate) { "use strict"; /** @@ -52,18 +52,12 @@ define( * @constructor */ function MCTForm() { - var templatePath = [ - "platform/forms", //MCTForm.bundle.path, - "res", //MCTForm.bundle.resources, - "templates/form.html" - ].join("/"); - return { // Only show at the element level restrict: "E", // Load the forms template - templateUrl: templatePath, + template: formTemplate, // Use FormController to populate/respond to changes in scope controller: [ '$scope', FormController ], diff --git a/platform/forms/src/MCTToolbar.js b/platform/forms/src/MCTToolbar.js index 0a31efc4fd..42c93c4842 100644 --- a/platform/forms/src/MCTToolbar.js +++ b/platform/forms/src/MCTToolbar.js @@ -25,8 +25,8 @@ * Module defining MCTForm. Created by vwoeltje on 11/10/14. */ define( - ["./controllers/FormController"], - function (FormController) { + ["./MCTForm", "text!../res/templates/toolbar.html"], + function (MCTForm, toolbarTemplate) { "use strict"; /** @@ -49,38 +49,14 @@ define( * @memberof platform/forms * @constructor */ - function MCTForm() { - var templatePath = [ - "platform/forms", //MCTForm.bundle.path, - "res", //MCTForm.bundle.resources, - "templates/toolbar.html" - ].join("/"); - - return { - // Only show at the element level - restrict: "E", - - // Load the forms template - templateUrl: templatePath, - - // Use FormController to populate/respond to changes in scope - controller: [ '$scope', FormController ], - - // Initial an isolate scope - scope: { - - // The model: Where form input will actually go - ngModel: "=", - - // Form structure; what sections/rows to show - structure: "=", - - // Name under which to publish the form - name: "@" - } - }; + function MCTToolbar() { + // Use Directive Definition Object from mct-form, + // but use the toolbar's template instead. + var ddo = new MCTForm(); + ddo.template = toolbarTemplate; + return ddo; } - return MCTForm; + return MCTToolbar; } ); diff --git a/platform/forms/test/MCTControlSpec.js b/platform/forms/test/MCTControlSpec.js index a743fd8e31..4f4b2cbd6f 100644 --- a/platform/forms/test/MCTControlSpec.js +++ b/platform/forms/test/MCTControlSpec.js @@ -29,6 +29,8 @@ define( describe("The mct-control directive", function () { var testControls, mockScope, + mockLinker, + mockChangeTemplate, mctControl; beforeEach(function () { @@ -46,8 +48,11 @@ define( ]; mockScope = jasmine.createSpyObj("$scope", [ "$watch" ]); + mockLinker = jasmine.createSpyObj("templateLinker", ["link"]); + mockChangeTemplate = jasmine.createSpy('changeTemplate'); + mockLinker.link.andReturn(mockChangeTemplate); - mctControl = new MCTControl(testControls); + mctControl = new MCTControl(mockLinker, testControls); }); it("is restricted to the element level", function () { @@ -66,14 +71,16 @@ define( it("changes its template dynamically", function () { mctControl.link(mockScope); + expect(mockChangeTemplate) + .not.toHaveBeenCalledWith(testControls[1]); + mockScope.key = "xyz"; mockScope.$watch.mostRecentCall.args[1]("xyz"); // Should have communicated the template path to // ng-include via the "inclusion" field in scope - expect(mockScope.inclusion).toEqual( - "x/y/z/template.html" - ); + expect(mockChangeTemplate) + .toHaveBeenCalledWith(testControls[1]); }); }); diff --git a/platform/persistence/queue/bundle.js b/platform/persistence/queue/bundle.js index 473e91a06d..00df156b0a 100644 --- a/platform/persistence/queue/bundle.js +++ b/platform/persistence/queue/bundle.js @@ -25,11 +25,13 @@ define([ "./src/QueuingPersistenceCapabilityDecorator", "./src/PersistenceQueue", "./src/PersistenceFailureController", + "text!./res/templates/persistence-failure-dialog.html", 'legacyRegistry' ], function ( QueuingPersistenceCapabilityDecorator, PersistenceQueue, PersistenceFailureController, + persistenceFailureDialogTemplate, legacyRegistry ) { "use strict"; @@ -67,7 +69,7 @@ define([ "templates": [ { "key": "persistence-failure-dialog", - "templateUrl": "templates/persistence-failure-dialog.html" + "template": persistenceFailureDialogTemplate } ], "controllers": [ diff --git a/platform/search/bundle.js b/platform/search/bundle.js index 3ad0c8b77f..7a0a9f4b9e 100644 --- a/platform/search/bundle.js +++ b/platform/search/bundle.js @@ -27,6 +27,9 @@ define([ "./src/controllers/ClickAwayController", "./src/services/GenericSearchProvider", "./src/services/SearchAggregator", + "text!./res/templates/search-item.html", + "text!./res/templates/search.html", + "text!./res/templates/search-menu.html", 'legacyRegistry' ], function ( SearchController, @@ -34,6 +37,9 @@ define([ ClickAwayController, GenericSearchProvider, SearchAggregator, + searchItemTemplate, + searchTemplate, + searchMenuTemplate, legacyRegistry ) { "use strict"; @@ -80,17 +86,17 @@ define([ "representations": [ { "key": "search-item", - "templateUrl": "templates/search-item.html" + "template": searchItemTemplate } ], "templates": [ { "key": "search", - "templateUrl": "templates/search.html" + "template": searchTemplate }, { "key": "search-menu", - "templateUrl": "templates/search-menu.html" + "template": searchMenuTemplate } ], "components": [ diff --git a/scripts/migrate-templates.js b/scripts/migrate-templates.js new file mode 100644 index 0000000000..4ada0c0ea3 --- /dev/null +++ b/scripts/migrate-templates.js @@ -0,0 +1,106 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed 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 + * 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. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + +// Converts all templateUrl references in bundle.js files to +// plain template references, loading said templates with the +// RequireJS text plugin. + +var glob = require('glob'), + fs = require('fs'), + path = require('path'), + _ = require('lodash'); + +function toTemplateName(templateUrl) { + var parts = templateUrl.split('/'); + return _.camelCase(parts[parts.length - 1].replace(".html", "")) + + "Template"; +} + +function getTemplateUrl(sourceLine) { + return _.trim(sourceLine.split(":")[1], "\", "); +} + +function hasTemplateUrl(sourceLine) { + return sourceLine.indexOf("templateUrl") !== -1; +} + +function findTemplateURLs(sourceCode) { + return sourceCode.split('\n') + .map(_.trim) + .filter(hasTemplateUrl) + .map(getTemplateUrl); +} + +function injectRequireArgument(sourceCode, templateUrls) { + var lines = sourceCode.split('\n'), + index; + + templateUrls = _.uniq(templateUrls); + + // Add arguments for source paths... + index = lines.map(_.trim).indexOf("'legacyRegistry'"); + lines = lines.slice(0, index).concat(templateUrls.map(function (url) { + return " \"text!./res/" + url + "\","; + }).concat(lines.slice(index))); + + /// ...and for arguments + index = lines.map(_.trim).indexOf("legacyRegistry"); + lines = lines.slice(0, index).concat(templateUrls.map(function (url) { + return " " + toTemplateName(url) + ","; + }).concat(lines.slice(index))); + + return lines.join('\n'); +} + +function rewriteUrl(sourceLine) { + return [ + sourceLine.substring(0, sourceLine.indexOf(sourceLine.trim())), + "\"template\": " + toTemplateName(getTemplateUrl(sourceLine)), + _.endsWith(sourceLine, ",") ? "," : "" + ].join(''); +} + +function rewriteLine(sourceLine) { + return hasTemplateUrl(sourceLine) ? + rewriteUrl(sourceLine.replace("templateUrl", "template")) : + sourceLine; +} + +function rewriteTemplateUrls(sourceCode) { + return sourceCode.split('\n').map(rewriteLine).join('\n'); +} + +function migrate(file) { + var sourceCode = fs.readFileSync(file, 'utf8'); + fs.writeFileSync(file, rewriteTemplateUrls( + injectRequireArgument(sourceCode, findTemplateURLs(sourceCode)) + ), 'utf8'); +} + +glob('platform/**/bundle.js', {}, function (err, files) { + if (err) { + console.log(err); + return; + } + + files.forEach(migrate); +});