Skip to content

Commit

Permalink
built dist fixed header
Browse files Browse the repository at this point in the history
  • Loading branch information
julienw committed Dec 18, 2014
1 parent 4d159df commit 57240a1
Showing 1 changed file with 174 additions and 20 deletions.
194 changes: 174 additions & 20 deletions dist/gaia-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ require('gaia-icons');
*/
var actionTypes = { menu: 1, back: 1, close: 1 };

const KNOWN_ATTRIBUTES = ['action', 'skip-init', 'start', 'end'];

/**
* Register the component.
*
Expand All @@ -183,6 +185,11 @@ module.exports = Component.register('gaia-header', {
* @private
*/
created: function() {
this.attrs = {};
this.runFontFitTimeout = null;

KNOWN_ATTRIBUTES.forEach((name) => this._updateAttribute(name));

this.createShadowRoot().innerHTML = this.template;

// Get els
Expand All @@ -194,7 +201,22 @@ module.exports = Component.register('gaia-header', {

this.els.actionButton.addEventListener('click', e => this.onActionButtonClick(e));
this.configureActionButton();
},

/**
* Initializes the component.
* It especially runs the font-fit algorithm once, and registers the
* textContent observer.
*
* @private
*/
init: function() {
if (this.attrs.skipInit !== null) {
return;
}

this.runFontFit();
this.addFontFitObserver();
},

/**
Expand All @@ -204,7 +226,14 @@ module.exports = Component.register('gaia-header', {
* @private
*/
attached: function() {
this.rerunFontFit();
this.init();
},

/**
* Called when the element is detached from the DOM
*/
detached: function() {
this.removeFontFitObserver();
},

/**
Expand All @@ -214,35 +243,91 @@ module.exports = Component.register('gaia-header', {
* @private
*/
attributeChanged: function(attr) {
if (KNOWN_ATTRIBUTES.indexOf(attr) === -1) {
return;
}

this._updateAttribute(attr);

if (attr === 'skip-init') {
setTimeout(() => this.init());
return;
}

if (attr === 'action') {
this.configureActionButton();
this.rerunFontFit();
}

this.runFontFitSoon();
},

/**
* Runs the logic to size and position
* header text inside the available space.
* Used to camel case a word containing dashes
*
* @private
*/
runFontFit: function() {
_camelCase: function ut_camelCase(str) {
return str.replace(/-(.)/g, function replacer(str, p1) {
return p1.toUpperCase();
});
},

/**
* Updates an attribute value in the internal attrs object
*
* @private
*/
_updateAttribute: function(name) {
var newVal = this.getAttribute(name);
this.attrs[this._camelCase(name)] = newVal;
},

/**
* Adds the textContent observer in the font fit library.
*
* @private
*/
addFontFitObserver: function() {
for (var i = 0; i < this.els.headings.length; i++) {
fontFit.reformatHeading(this.els.headings[i]);
fontFit.observeHeadingChanges(this.els.headings[i]);
}
},

/**
* Rerun font-fit logic.
* Removes the textContent observer in the font fit library.
*
* TODO: We really need an official API for this.
* @private
*/
removeFontFitObserver: function() {
fontFit.disconnectHeadingObserver();
},

/**
* This function will debounce the use of runFontFit. This is used in
* attributeChanged so that the component user can change different attributes
* and still have runFontFit run once.
*
* @private
*/
rerunFontFit: function() {
runFontFitSoon: function() {
clearTimeout (this.runFontFitTimeout);
this.runFontFitTimeout = setTimeout(() => this.runFontFit());
},

/**
* Runs the logic to size and position
* header text inside the available space.
*
* @private
*/
runFontFit: function() {
for (var i = 0; i < this.els.headings.length; i++) {
fontFit.reformatHeading(this.els.headings[i]);
var heading = this.els.headings[i];
var start = parseInt(this.attrs.start);
var end = parseInt(this.attrs.end);
start = isNaN(start) ? null : start;
end = isNaN(end) ? null : end;
fontFit.reformatHeading(heading, start, end);
}
},

Expand All @@ -253,7 +338,7 @@ module.exports = Component.register('gaia-header', {
* @public
*/
triggerAction: function() {
if (this.isSupportedAction(this.getAttribute('action'))) {
if (this.isSupportedAction(this.attrs.action)) {
this.els.actionButton.click();
}
},
Expand All @@ -267,7 +352,7 @@ module.exports = Component.register('gaia-header', {
*/
configureActionButton: function() {
var old = this.els.actionButton.getAttribute('icon');
var type = this.getAttribute('action');
var type = this.attrs.action;
var supported = this.isSupportedAction(type);
this.els.actionButton.classList.remove('icon-' + old);
this.els.actionButton.setAttribute('icon', type);
Expand All @@ -281,7 +366,7 @@ module.exports = Component.register('gaia-header', {
* @private
*/
isSupportedAction: function(action) {
return action && actionTypes[action];
return !!(action && actionTypes[action]);
},

/**
Expand All @@ -295,7 +380,7 @@ module.exports = Component.register('gaia-header', {
* @private
*/
onActionButtonClick: function(e) {
var config = { detail: { type: this.getAttribute('action') } };
var config = { detail: { type: this.attrs.action } };
var actionEvent = new CustomEvent('action', config);
setTimeout(this.dispatchEvent.bind(this, actionEvent));
},
Expand Down Expand Up @@ -583,6 +668,22 @@ return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-header',this));
},{"./lib/font-fit":4,"gaia-component":1,"gaia-icons":2}],4:[function(require,module,exports){
;(function(define){'use strict';define(function(require,exports,module){

var privMap = new WeakMap();

function getPriv(instance) {
var privMembers = privMap.get(instance);

if (!privMembers) {
privMembers = {
start: null,
end: null
};
privMap.set(instance, privMembers);
}

return privMembers;
}

/**
* Utility functions for measuring and manipulating font sizes
*/
Expand All @@ -605,23 +706,61 @@ return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-header',this));
observer.observe(heading, { childList: true });
},

/**
* Stops the observer from observing the heading changes.
*/
disconnectHeadingObserver: function() {
var observer = this._getTextChangeObserver();
observer.disconnect();
},

/**
* Resize and reposition the header text based on string length and
* container position.
* container position
*
* @param {HTMLHeadingElement} heading h1 text inside header to reformat.
* @param {Number} start Offset in pixels between the start of the text
* container and the start of the inner window.
* @param {Number} end Offset in pixels between the end of the text
* container and the end of the inner window.
*/
reformatHeading: function(heading) {
reformatHeading: function(heading, start, end) {
// Skip resize logic if header has no content, ie before localization.
if (!heading || heading.textContent.trim() === '') {
return;
}

var style;
var priv = getPriv(heading);
if (start !== undefined) {
priv.start = start;
}

if (end !== undefined) {
priv.end = end;
}

start = priv.start;
end = priv.end;

var hasSizeInformation = start !== null || end !== null;

// Reset our centering styles.
this._resetCentering(heading);

// Cache the element style properties to avoid reflows.
var style = this._getStyleProperties(heading);
if (hasSizeInformation) {
style = {
fontFamily: 'sans-serif',
contentWidth: this._getWindowWidth() - (start || 0) - (end || 0),
paddingRight: 0,
paddingLeft: 0,
offsetLeft: start || 0,
rtlFriendly: true
};
} else {
// Cache the element style properties to avoid reflows.
style = this._getStyleProperties(heading);
}

// If the document is inside a hidden iframe
// `window.getComputedStyle()` returns null,
Expand Down Expand Up @@ -858,6 +997,7 @@ return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-header',this));
// We need to set the lateral margins to 0 to be able to measure the
// element width properly. All previously set values are ignored.
heading.style.marginLeft = heading.style.marginRight = '0';
heading.style.MozMarginStart = heading.style.MozMarginEnd = '0';
},

/**
Expand Down Expand Up @@ -891,6 +1031,20 @@ return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-header',this));
return;
}

var propLeft, propRight;
if (styleOptions.rtlFriendly) {
propLeft = 'MozMarginStart';
propRight = 'MozMarginEnd';
} else {
propLeft = 'marginLeft';
propRight = 'marginRight';
}

// reset the previous value
['marginLeft', 'marginRight', 'MozMarginStart', 'MozMarginEnd'].forEach(
(prop) => delete heading.style[prop]
);

// To center, we need to make sure the space to the left of the header
// is the same as the space to the right, so take the largest of the two.
var margin = Math.max(sideSpaceLeft, sideSpaceRight);
Expand All @@ -901,10 +1055,10 @@ return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-header',this));
// See https://bugzil.la/1026955
if (minHeaderWidth + (margin * 2) < this._getWindowWidth() - 1) {
if (sideSpaceLeft < sideSpaceRight) {
heading.style.marginLeft = (sideSpaceRight - sideSpaceLeft) + 'px';
heading.style[propLeft] = (sideSpaceRight - sideSpaceLeft) + 'px';
}
if (sideSpaceRight < sideSpaceLeft) {
heading.style.marginRight = (sideSpaceLeft - sideSpaceRight) + 'px';
heading.style[propRight] = (sideSpaceLeft - sideSpaceRight) + 'px';
}
}
},
Expand Down

0 comments on commit 57240a1

Please sign in to comment.