Repository: couchdb-fauxton Updated Branches: refs/heads/master 380b277c4 -> e08faa5dd
New lookahead-tray component You can see the component by going to a database, then clicking on the database name. That will open up a tray where you can type to get a list of other matching databases. Clicking <enter> or selecting the item from the list will take you to that particular DB page. Closes COUCHDB-2420 Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/e08faa5d Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/e08faa5d Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/e08faa5d Branch: refs/heads/master Commit: e08faa5dddf61bca66ce1da0f20944555276ce54 Parents: 380b277 Author: Benjamin Keen <[email protected]> Authored: Thu Oct 30 18:02:39 2014 -0700 Committer: Benjamin Keen <[email protected]> Committed: Tue Nov 11 08:52:58 2014 -0800 ---------------------------------------------------------------------- app/addons/databases/resources.js | 6 + app/addons/databases/tests/resourcesSpec.js | 15 ++ app/addons/databases/views.js | 19 +-- app/addons/documents/routes-documents.js | 56 +++++-- app/addons/fauxton/components.js | 160 +++++++++++++++++-- app/addons/fauxton/templates/breadcrumbs.html | 8 +- app/addons/fauxton/templates/header_left.html | 6 +- .../fauxton/templates/lookahead_tray.html | 16 ++ app/core/api.js | 6 +- app/core/router.js | 1 - app/main.js | 15 +- assets/less/trays.less | 104 ++++++++++++ 12 files changed, 362 insertions(+), 50 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/addons/databases/resources.js ---------------------------------------------------------------------- diff --git a/app/addons/databases/resources.js b/app/addons/databases/resources.js index 159f03a..f580ebf 100644 --- a/app/addons/databases/resources.js +++ b/app/addons/databases/resources.js @@ -162,6 +162,12 @@ function(app, FauxtonAPI, Documents) { return "all_dbs"; }, + getDatabaseNames: function () { + return _.map(this.toArray(), function (model) { + return model.get('name'); + }); + }, + cache: { expires: 60 }, http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/addons/databases/tests/resourcesSpec.js ---------------------------------------------------------------------- diff --git a/app/addons/databases/tests/resourcesSpec.js b/app/addons/databases/tests/resourcesSpec.js index 8e3fee4..2980dd2 100644 --- a/app/addons/databases/tests/resourcesSpec.js +++ b/app/addons/databases/tests/resourcesSpec.js @@ -35,5 +35,20 @@ define([ assert.ok(!modelWithoutGraveYard.isGraveYard()); }); }); + + describe('List of Databases', function () { + it('returns the names of databases in a list in an array', function () { + var listCollection = new Resources.List([{ + name: 'ente' + }, + { + name: 'rocko' + }]); + var databaseNames = listCollection.getDatabaseNames(); + + assert.equal(databaseNames[0], 'ente'); + assert.equal(databaseNames[1], 'rocko'); + }); + }); }); }); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/addons/databases/views.js ---------------------------------------------------------------------- diff --git a/app/addons/databases/views.js b/app/addons/databases/views.js index a6fd499..cefc72d 100644 --- a/app/addons/databases/views.js +++ b/app/addons/databases/views.js @@ -122,12 +122,13 @@ function(app, Components, FauxtonAPI, Databases) { var JumpToDBView = FauxtonAPI.View.extend({ template: 'addons/databases/templates/jump_to_db', events: { - 'submit form#jump-to-db': 'switchDatabase' + 'submit form#jump-to-db': 'switchDatabaseHandler' }, initialize: function () { var params = app.getParams(); this.page = params.page ? parseInt(params.page, 10) : 1; + this.listenTo(FauxtonAPI.Events, 'jumptodb:update', this.switchDatabase); }, establish: function () { @@ -144,9 +145,7 @@ function(app, Components, FauxtonAPI, Databases) { return [deferred]; }, - switchDatabase: function (event, selectedName) { - event && event.preventDefault(); - + switchDatabase: function (selectedName) { var dbname = this.$el.find('[name="search-query"]').val().trim(); if (selectedName) { @@ -166,18 +165,20 @@ function(app, Components, FauxtonAPI, Databases) { } }, + switchDatabaseHandler: function (event) { + event.preventDefault(); + this.switchDatabase(); + }, + afterRender: function () { - var that = this, - AllDBsArray = _.map(this.collection.toJSON(), function (item, key) { + var AllDBsArray = _.map(this.collection.toJSON(), function (item, key) { return item.name; }); this.dbSearchTypeahead = new Components.Typeahead({ el: 'input.search-autocomplete', source: AllDBsArray, - onUpdate: function (item) { - that.switchDatabase(null, item); - } + onUpdateEventName: 'jumptodb:update' }); this.dbSearchTypeahead.render(); this.$el.find('.js-db-graveyard').tooltip(); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/addons/documents/routes-documents.js ---------------------------------------------------------------------- diff --git a/app/addons/documents/routes-documents.js b/app/addons/documents/routes-documents.js index 8b7f251..32523f5 100644 --- a/app/addons/documents/routes-documents.js +++ b/app/addons/documents/routes-documents.js @@ -28,18 +28,19 @@ define([ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resources, Components) { + // TODO these are the same. Legacy code? var crumbs = { allDocs: function (database) { return [ - {"name": "", "className": "fonticon-left-open", "link": "/_all_dbs"}, - {"name": database.id, "link": Databases.databaseUrl(database)} + { "name": "", "className": "fonticon-left-open", "link": "/_all_dbs" }, + { "name": database.id, "link": Databases.databaseUrl(database), className: "lookahead-tray-link" } ]; }, changes: function (database) { return [ - {"name": "", "className": "fonticon-left-open", "link": "/_all_dbs"}, - {"name": database.id, "link": Databases.databaseUrl(database)} + { "name": "", "className": "fonticon-left-open", "link": "/_all_dbs" }, + { "name": database.id, "link": Databases.databaseUrl(database), className: "lookahead-tray-link" } ]; } }; @@ -92,8 +93,15 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou overrideBreadcrumbs: true, initialize: function (route, masterLayout, options) { - this.databaseName = options[0]; - this.database = new Databases.Model({id:this.databaseName}); + this.initViews(options[0]); + this.listenTo(FauxtonAPI.Events, 'lookaheadTray:update', this.onSelectDatabase); + }, + + initViews: function (dbName) { + this.databaseName = dbName; + this.database = new Databases.Model({id: this.databaseName}); + this.allDatabases = new Databases.List(); + this.designDocs = new Documents.AllDocs(null, { database: this.database, paging: { @@ -113,7 +121,13 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou this.leftheader = this.setView("#breadcrumbs", new Components.LeftHeader({ crumbs: crumbs.allDocs(this.database), - dropdownMenu: this.setUpDropdown() + dropdownMenu: this.setUpDropdown(), + lookaheadTrayOptions: { + databaseCollection: this.allDatabases, + toggleEventName: 'lookaheadTray:toggle', + onUpdateEventName: 'lookaheadTray:update', + placeholder: 'Enter database name' + } })); this.sidebar = this.setView("#sidebar-content", new Documents.Views.Sidebar({ @@ -122,6 +136,15 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou })); }, + // this safely assumes the db name is valid + onSelectDatabase: function (dbName) { + this.cleanup(); + this.initViews(dbName); + FauxtonAPI.navigate('/database/' + app.utils.safeURLName(dbName) + '/_all_docs', { + trigger: true + }); + }, + setUpDropdown: function() { var defaultMenuLinks = [{ links: [{ @@ -194,7 +217,7 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou }, establish: function () { - return this.designDocs.fetch({reset: true}); + return [this.designDocs.fetch({reset: true}), this.allDatabases.fetchOnce()]; }, createParams: function (options) { @@ -224,6 +247,7 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou } this.leftheader.updateCrumbs(crumbs.allDocs(this.database)); + this.database.buildAllDocs(docParams); if (docParams.startkey && docParams.startkey.indexOf("_design") > -1) { @@ -243,9 +267,9 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou bulkDeleteDocsCollection: new Documents.BulkDeleteDocCollection([], {databaseId: this.database.get('id')}) })); - this.apiUrl = function() { - return [this.database.allDocs.urlRef("apiurl", urlParams), this.database.allDocs.documentation()]; - }; + // this used to be a function that returned the object, but be warned: it caused a closure with a reference to + // the initial this.database object which can change + this.apiUrl = [this.database.allDocs.urlRef("apiurl", urlParams), this.database.allDocs.documentation()]; // update the rightHeader with the latest & greatest info this.rightHeader.resetQueryOptions({ queryParams: urlParams }); @@ -493,7 +517,17 @@ function(app, FauxtonAPI, Documents, Changes, Index, DocEditor, Databases, Resou updateQueryOptions: function(options) { this.rightHeader.updateQueryOptions(options); + }, + + cleanup: function () { + if (this.leftheader) { + this.removeView('#breadcrumbs'); + } + if (this.sidebar) { + this.removeView('#sidebar'); + } } + }); return DocumentsRouteObject; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/addons/fauxton/components.js ---------------------------------------------------------------------- diff --git a/app/addons/fauxton/components.js b/app/addons/fauxton/components.js index a148f21..19c49c4 100644 --- a/app/addons/fauxton/components.js +++ b/app/addons/fauxton/components.js @@ -26,6 +26,7 @@ define([ "api", "ace_configuration", "spin", + // this should never be global available: // https://github.com/zeroclipboard/zeroclipboard/blob/master/docs/security.md "plugins/zeroclipboard/ZeroClipboard", @@ -35,32 +36,57 @@ define([ function(app, FauxtonAPI, ace, spin, ZeroClipboard) { var Components = FauxtonAPI.addon(); - //setting up the left header with the backbutton used in Views and All docs + // setting up the left header with the backbutton used in Views and All docs Components.LeftHeader = FauxtonAPI.View.extend({ className: "header-left", template: "addons/fauxton/templates/header_left", - initialize:function(options){ + + initialize: function (options) { this.dropdownEvents = options.dropdownEvents; this.dropdownMenuLinks = options.dropdownMenu; + this.lookaheadTrayOptions = options.lookaheadTrayOptions || null; this.crumbs = options.crumbs || []; + + // listen for breadcrumb clicks + this.listenTo(FauxtonAPI.Events, 'breadcrumb:click', this.toggleTray); + this.listenTo(FauxtonAPI.Events, 'lookaheadTray:close', this.unselectLastBreadcrumb); }, + updateCrumbs: function(crumbs){ this.crumbs = crumbs; this.breadcrumbs && this.breadcrumbs.update(crumbs); }, + + unselectLastBreadcrumb: function () { + this.breadcrumbs.unselectLastBreadcrumb(); + }, + updateDropdown: function(menuLinks){ this.dropdownMenuLinks = menuLinks; this.dropdown && this.dropdown.update(menuLinks); }, + + toggleTray: function () { + if (this.lookaheadTray !== null) { + this.lookaheadTray.toggleTray(); + } + }, + beforeRender: function(){ this.setUpCrumbs(); this.setUpDropDownMenu(); + + if (this.lookaheadTray !== null) { + this.setUpLookaheadTray(); + } }, + setUpCrumbs: function(){ this.breadcrumbs = this.insertView("#header-breadcrumbs", new Components.Breadcrumbs({ crumbs: this.crumbs })); }, + setUpDropDownMenu: function(){ if (this.dropdownMenuLinks){ this.dropdown = this.insertView("#header-dropdown-menu", new Components.MenuDropDown({ @@ -69,6 +95,22 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) { events: this.dropdownEvents })); } + }, + + setUpLookaheadTray: function () { + var options = this.lookaheadTrayOptions, + dbNames = options.databaseCollection.getDatabaseNames(), + currentDBName = this.crumbs[1].name; + + // remove the current database name from the list + dbNames = _.without(dbNames, currentDBName); + + this.lookaheadTray = this.insertView("#header-lookahead", new Components.LookaheadTray({ + data: dbNames, + toggleEventName: options.toggleEventName, + onUpdateEventName: options.onUpdateEventName, + placeholder: options.placeholder + })); } }); @@ -76,6 +118,11 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) { className: "breadcrumb pull-left", tagName: "ul", template: "addons/fauxton/templates/breadcrumbs", + + events: { + "click .js-lastelement": "toggleLastElement" + }, + serialize: function() { var crumbs = _.clone(this.crumbs); @@ -90,15 +137,27 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) { nextCrumbHasLabel: nextCrumbHasLabel }; }, + + toggleLastElement: function (event) { + this.$(event.currentTarget).toggleClass('js-enabled'); + FauxtonAPI.Events.trigger('breadcrumb:click'); + }, + + unselectLastBreadcrumb: function () { + this.$('.js-enabled').removeClass('js-enabled'); + }, + update: function(crumbs) { this.crumbs = crumbs; this.render(); }, + initialize: function(options) { this.crumbs = options.crumbs; } }); + Components.ApiBar = FauxtonAPI.View.extend({ template: "addons/fauxton/templates/api_bar", @@ -423,38 +482,29 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) { } }); - //TODO allow more of the typeahead options. - //Current this just does what we need but we - //need to support the other typeahead options. Components.Typeahead = FauxtonAPI.View.extend({ initialize: function (options) { this.source = options.source; - this.onUpdate = options.onUpdate; - _.bindAll(this); + this.onUpdateEventName = options.onUpdateEventName; }, afterRender: function () { - var onUpdate = this.onUpdate; + var onUpdateEventName = this.onUpdateEventName; this.$el.typeahead({ source: this.source, updater: function (item) { - if (onUpdate) { - onUpdate(item); - } - + FauxtonAPI.Events.trigger(onUpdateEventName, item); return item; } }); } - }); Components.DbSearchTypeahead = Components.Typeahead.extend({ initialize: function (options) { this.dbLimit = options.dbLimit || 30; - this.onUpdate = options.onUpdate; _.bindAll(this); }, source: function(query, process) { @@ -845,12 +895,93 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) { on: function () { return this.client.on.apply(this.client, arguments); } + }); + + Components.LookaheadTray = FauxtonAPI.View.extend({ + className: "lookahead-tray tray", + template: "addons/fauxton/templates/lookahead_tray", + placeholder: "Enter to search", + + events: { + 'click #js-close-tray': 'closeTray', + 'keyup': 'onKeyup' + }, + + serialize: function () { + return { + placeholder: this.placeholder + }; + }, + + initialize: function (opts) { + this.data = opts.data; + this.toggleEventName = opts.toggleEventName; + this.onUpdateEventName = opts.onUpdateEventName; + + var trayIsVisible = _.bind(this.trayIsVisible, this); + var closeTray = _.bind(this.closeTray, this); + $("body").on("click.lookaheadTray", function (e) { + if (!trayIsVisible()) { return; } + if ($(e.target).closest(".lookahead-tray").length === 0 && + $(e.target).closest('.lookahead-tray-link').length === 0) { + closeTray(); + } + }); + }, + + afterRender: function () { + var that = this; + this.dbSearchTypeahead = new Components.Typeahead({ + el: 'input.search-autocomplete', + source: that.data, + onUpdateEventName: that.onUpdateEventName + }); + this.dbSearchTypeahead.render(); + }, + + cleanup: function () { + $("body").off("click.lookaheadTray"); + }, + + trayIsVisible: function () { + return this.$el.is(":visible"); + }, + + toggleTray: function () { + if (this.trayIsVisible()) { + this.closeTray(); + } else { + this.openTray(); + } + }, + + openTray: function () { + this.$el.velocity("transition.slideDownIn", FauxtonAPI.constants.TRAY_TOGGLE_SPEED, function () { + this.$el.find('input').focus(); + }.bind(this)); + + }, + + closeTray: function () { + var $tray = this.$el; + $tray.velocity("reverse", FauxtonAPI.constants.TRAY_TOGGLE_SPEED, function () { + $tray.hide(); + }); + FauxtonAPI.Events.trigger('lookaheadTray:close'); + }, + + onKeyup: function (e) { + if (e.which === 27) { + this.closeTray(); + } + } }); //need to make this into a backbone view... var routeObjectSpinner; + FauxtonAPI.RouteObject.on('beforeEstablish', function (routeObject) { if (!routeObject.disableLoader){ var opts = { @@ -931,4 +1062,3 @@ function(app, FauxtonAPI, ace, spin, ZeroClipboard) { return Components; }); - http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/addons/fauxton/templates/breadcrumbs.html ---------------------------------------------------------------------- diff --git a/app/addons/fauxton/templates/breadcrumbs.html b/app/addons/fauxton/templates/breadcrumbs.html index 512b69c..ead2d6c 100644 --- a/app/addons/fauxton/templates/breadcrumbs.html +++ b/app/addons/fauxton/templates/breadcrumbs.html @@ -1,4 +1,4 @@ -<!-- +<%/* 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 @@ -10,7 +10,7 @@ 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. ---> +*/%> <% _.each(_.initial(crumbs), function(crumb, index) { %> <li class="pull-left"> @@ -23,5 +23,5 @@ the License. <% }); %> -<% var last = _.last(crumbs) || {name: ''} %> -<li class="active" title="<%- last.name %>"><%- last.name %></li> +<% var last = _.last(crumbs) || {name: '', className: '', dataEvent: ''} %> +<li class="js-lastelement active <%- last.className %>" title="<%- last.name %>"><%- last.name %></li> http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/addons/fauxton/templates/header_left.html ---------------------------------------------------------------------- diff --git a/app/addons/fauxton/templates/header_left.html b/app/addons/fauxton/templates/header_left.html index 420b90b..e7d48d1 100644 --- a/app/addons/fauxton/templates/header_left.html +++ b/app/addons/fauxton/templates/header_left.html @@ -13,5 +13,9 @@ the License. --> <!--back arrow--> <div id="header-breadcrumbs"></div> - <!-- Menu gear--> + +<!-- Menu gear--> <div id="header-dropdown-menu" class="add-dropdown"></div> + +<!-- lookahead tray --> +<div id="header-lookahead"></div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/addons/fauxton/templates/lookahead_tray.html ---------------------------------------------------------------------- diff --git a/app/addons/fauxton/templates/lookahead_tray.html b/app/addons/fauxton/templates/lookahead_tray.html new file mode 100644 index 0000000..d7f3cc4 --- /dev/null +++ b/app/addons/fauxton/templates/lookahead_tray.html @@ -0,0 +1,16 @@ +<%/* +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. +*/%> +<input type="text" class="search-autocomplete" placeholder="<%-placeholder%>" /> +<button class="btn btn-primary search-btn" type="submit"><i class="icon icon-search"></i></button> +<div id="js-close-tray" class="fonticon-cancel"></div> http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/core/api.js ---------------------------------------------------------------------- diff --git a/app/core/api.js b/app/core/api.js index a144521..b794b53 100644 --- a/app/core/api.js +++ b/app/core/api.js @@ -18,7 +18,7 @@ define([ 'core/utils' ], -function(FauxtonAPI, Layout, Router, RouteObject, utils, constants) { +function(FauxtonAPI, Layout, Router, RouteObject, utils) { FauxtonAPI = _.extend(FauxtonAPI, { Layout: Layout, Router: Router, @@ -29,8 +29,8 @@ function(FauxtonAPI, Layout, Router, RouteObject, utils, constants) { FauxtonAPI.Events = _.extend({}, Backbone.Events); FauxtonAPI.navigate = function (url, _opts) { - var options = _.extend({trigger: true}, _opts ); - FauxtonAPI.router.navigate(url,options); + var options = _.extend({trigger: true}, _opts); + FauxtonAPI.router.navigate(url, options); }; FauxtonAPI.beforeUnload = function () { http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/core/router.js ---------------------------------------------------------------------- diff --git a/app/core/router.js b/app/core/router.js index 1982f88..a4c36e7 100644 --- a/app/core/router.js +++ b/app/core/router.js @@ -60,7 +60,6 @@ function(FauxtonAPI, Auth, Backbone) { authPromise.then(function () { if (!that.activeRouteObject || !that.activeRouteObject.hasRoute(route)) { that.activeRouteObject && that.activeRouteObject.cleanup(); - that.activeRouteObject = new RouteObject(route, masterLayout, args); } http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/app/main.js ---------------------------------------------------------------------- diff --git a/app/main.js b/app/main.js index 9df15c5..7799a13 100644 --- a/app/main.js +++ b/app/main.js @@ -11,10 +11,10 @@ // the License. require([ - // Application. - "app", - "api", - "load_addons" + // Application + "app", + "api", + "load_addons" ], function(app, FauxtonAPI, LoadAddons) { @@ -25,15 +25,19 @@ function(app, FauxtonAPI, LoadAddons) { // root folder to '/' by default. Change in app.js. Backbone.history.start({ pushState: false, root: app.root }); + // All navigation that is relative should be passed through the navigate // method, to be processed by the router. If the link has a `data-bypass` // attribute, bypass the delegation completely. $(document).on("click", "a:not([data-bypass])", function(evt) { + // Get the absolute anchor href. var href = { prop: $(this).prop("href"), attr: $(this).attr("href") }; + // Get the absolute root. var root = location.protocol + "//" + location.host + app.root; - // Ensure the root is part of the anchor href, meaning it's relative. + + // Ensure the root is part of the anchor href, meaning it's relative if (href.prop && href.prop.slice(0, root.length) === root) { // Stop the default event to ensure the link will not cause a page // refresh. @@ -42,6 +46,5 @@ function(app, FauxtonAPI, LoadAddons) { //User app navigate so that navigate goes through a central place app.router.navigate(href.attr, true); } - }); }); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/e08faa5d/assets/less/trays.less ---------------------------------------------------------------------- diff --git a/assets/less/trays.less b/assets/less/trays.less index ddffd08..8d6b28a 100644 --- a/assets/less/trays.less +++ b/assets/less/trays.less @@ -10,6 +10,7 @@ * License for the specific language governing permissions and limitations under * the License. */ +@import "bootstrap/mixins.less"; .tray { .bottom-left-shadow-border; @@ -80,3 +81,106 @@ width: 0; height: 0; } + +.lookahead-tray-link { + cursor: pointer; + position: relative; /* ensures :after elements are also hidden when overflowed */ +} + +.lookahead-tray-link:after { + content: "\f14a"; + font-family: "fauxtonicon"; + font-style: normal; + font-weight: normal; + font-variant: normal; + line-height: 1; + text-decoration: inherit; + text-rendering: optimizeLegibility; + text-transform: none; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + font-smoothing: antialiased; + font-size: 8px; + color: #777; + margin: 8px; + display: inline-block; + position:absolute; + .rotate(90deg); +} + +.lookahead-tray-link.js-enabled:after { + color: @orange; +} + +#breadcrumbs .breadcrumb li.active.js-enabled { + color: @red; +} + +.lookahead-tray.tray { + width: 298px; + padding: 0px; + right: 16px; + border: none; + + &:before { + left: 132px; + } + input { + margin: 10px; + padding-right: 30px; + font-size: 16px; + width: 244px; + } + + .search-btn { + background: transparent; + margin-left: -38px; + margin-right: 20px; + border: 0px; + padding: 0px; + color: #cccccc; + } + + .dropdown-menu { + position: relative; + border: 0px; + background-color: #3333333; + + /* unfortunate, but the typeahead plugin adds these values inline */ + left: 0px !important; + top: 0px !important; + + width: 298px; + text-overflow: ellipsis; + overflow: hidden; + + & > li { + overflow: hidden; + text-overflow: ellipsis; + + & > a { + text-overflow: ellipsis; + padding: 10px 20px; + font-size: 16px; + overflow: hidden; + } + + strong { + color: @white; + } + } + } + + .fonticon-cancel { + display: inline-block; + width: 20px; + height: 20px; + font-size: 12px; + color: #cccccc; + cursor: pointer; + } +} + +#header-lookahead .dropdown-menu li.active { + width: 100%; +}
