UNPKG

infusion

Version:

Infusion is an application framework for developing flexible stuff with JavaScript

432 lines (387 loc) 16.7 kB
/* Copyright 2013-2016 OCAD University Copyright 2015 Raising the Floor - International Licensed under the Educational Community License (ECL), Version 2.0 or the New BSD license. You may not use this file except in compliance with one these Licenses. You may obtain a copy of the ECL 2.0 License and BSD License at https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt */ var fluid_2_0_0 = fluid_2_0_0 || {}; (function ($, fluid) { "use strict"; fluid.defaults("fluid.prefs.enactor", { gradeNames: ["fluid.modelComponent"] }); /********************************************************************************** * styleElements * * Adds or removes the classname to/from the elements based upon the model value. * This component is used as a grade by emphasizeLinks & inputsLarger **********************************************************************************/ fluid.defaults("fluid.prefs.enactor.styleElements", { gradeNames: ["fluid.prefs.enactor"], cssClass: null, // Must be supplied by implementors elementsToStyle: null, // Must be supplied by implementors invokers: { applyStyle: { funcName: "fluid.prefs.enactor.styleElements.applyStyle", args: ["{arguments}.0", "{arguments}.1"] }, resetStyle: { funcName: "fluid.prefs.enactor.styleElements.resetStyle", args: ["{arguments}.0", "{arguments}.1"] }, handleStyle: { funcName: "fluid.prefs.enactor.styleElements.handleStyle", args: ["{arguments}.0", "{that}.options.elementsToStyle", "{that}.options.cssClass", "{that}.applyStyle", "{that}.resetStyle"] } }, modelListeners: { value: { listener: "{that}.handleStyle", args: ["{change}.value"] } } }); fluid.prefs.enactor.styleElements.applyStyle = function (elements, cssClass) { elements.addClass(cssClass); }; fluid.prefs.enactor.styleElements.resetStyle = function (elements, cssClass) { $(elements, "." + cssClass).addBack().removeClass(cssClass); }; fluid.prefs.enactor.styleElements.handleStyle = function (value, elements, cssClass, applyStyleFunc, resetStyleFunc) { var func = value ? applyStyleFunc : resetStyleFunc; func(elements, cssClass); }; /******************************************************************************* * ClassSwapper * * Has a hash of classes it cares about and will remove all those classes from * its container before setting the new class. * This component tends to be used as a grade by textFont and contrast *******************************************************************************/ fluid.defaults("fluid.prefs.enactor.classSwapper", { gradeNames: ["fluid.prefs.enactor", "fluid.viewComponent"], classes: {}, // Must be supplied by implementors invokers: { clearClasses: { funcName: "fluid.prefs.enactor.classSwapper.clearClasses", args: ["{that}.container", "{that}.classStr"] }, swap: { funcName: "fluid.prefs.enactor.classSwapper.swap", args: ["{arguments}.0", "{that}", "{that}.clearClasses"] } }, modelListeners: { value: { listener: "{that}.swap", args: ["{change}.value"] } }, members: { classStr: { expander: { func: "fluid.prefs.enactor.classSwapper.joinClassStr", args: "{that}.options.classes" } } } }); fluid.prefs.enactor.classSwapper.clearClasses = function (container, classStr) { container.removeClass(classStr); }; fluid.prefs.enactor.classSwapper.swap = function (value, that, clearClassesFunc) { clearClassesFunc(); that.container.addClass(that.options.classes[value]); }; fluid.prefs.enactor.classSwapper.joinClassStr = function (classes) { var classStr = ""; fluid.each(classes, function (oneClassName) { if (oneClassName) { classStr += classStr ? " " + oneClassName : oneClassName; } }); return classStr; }; /******************************************************************************* * emphasizeLinks * * The enactor to emphasize links in the container according to the value *******************************************************************************/ // Note that the implementors need to provide the container for this view component fluid.defaults("fluid.prefs.enactor.emphasizeLinks", { gradeNames: ["fluid.prefs.enactor.styleElements", "fluid.viewComponent"], preferenceMap: { "fluid.prefs.emphasizeLinks": { "model.value": "default" } }, cssClass: null, // Must be supplied by implementors elementsToStyle: "{that}.container" }); /******************************************************************************* * inputsLarger * * The enactor to enlarge inputs in the container according to the value *******************************************************************************/ // Note that the implementors need to provide the container for this view component fluid.defaults("fluid.prefs.enactor.inputsLarger", { gradeNames: ["fluid.prefs.enactor.styleElements", "fluid.viewComponent"], preferenceMap: { "fluid.prefs.inputsLarger": { "model.value": "default" } }, cssClass: null, // Must be supplied by implementors elementsToStyle: "{that}.container" }); /******************************************************************************* * textFont * * The enactor to change the font face used according to the value *******************************************************************************/ // Note that the implementors need to provide the container for this view component fluid.defaults("fluid.prefs.enactor.textFont", { gradeNames: ["fluid.prefs.enactor.classSwapper"], preferenceMap: { "fluid.prefs.textFont": { "model.value": "default" } } }); /******************************************************************************* * contrast * * The enactor to change the contrast theme according to the value *******************************************************************************/ // Note that the implementors need to provide the container for this view component fluid.defaults("fluid.prefs.enactor.contrast", { gradeNames: ["fluid.prefs.enactor.classSwapper"], preferenceMap: { "fluid.prefs.contrast": { "model.value": "default" } } }); /******************************************************************************* * Functions shared by textSize and lineSpace *******************************************************************************/ /** * return "font-size" in px * @param (Object) container * @param (Object) fontSizeMap: the mapping between the font size string values ("small", "medium" etc) to px values */ fluid.prefs.enactor.getTextSizeInPx = function (container, fontSizeMap) { var fontSize = container.css("font-size"); if (fontSizeMap[fontSize]) { fontSize = fontSizeMap[fontSize]; } // return fontSize in px return parseFloat(fontSize); }; /******************************************************************************* * textSize * * Sets the text size on the root element to the multiple provided. *******************************************************************************/ // Note that the implementors need to provide the container for this view component fluid.defaults("fluid.prefs.enactor.textSize", { gradeNames: ["fluid.prefs.enactor", "fluid.viewComponent"], preferenceMap: { "fluid.prefs.textSize": { "model.value": "default" } }, members: { root: { expander: { "this": "{that}.container", "method": "closest", // ensure that the correct document is being used. i.e. in an iframe "args": ["html"] } } }, fontSizeMap: {}, // must be supplied by implementors invokers: { set: { funcName: "fluid.prefs.enactor.textSize.set", args: ["{arguments}.0", "{that}", "{that}.getTextSizeInPx"] }, getTextSizeInPx: { funcName: "fluid.prefs.enactor.getTextSizeInPx", args: ["{that}.root", "{that}.options.fontSizeMap"] } }, modelListeners: { value: { listener: "{that}.set", args: ["{change}.value"] } } }); fluid.prefs.enactor.textSize.set = function (times, that, getTextSizeInPxFunc) { times = times || 1; // Calculating the initial size here rather than using a members expand because the "font-size" // cannot be detected on hidden containers such as separated paenl iframe. if (!that.initialSize) { that.initialSize = getTextSizeInPxFunc(); } if (that.initialSize) { var targetSize = times * that.initialSize; that.root.css("font-size", targetSize + "px"); } }; /******************************************************************************* * lineSpace * * Sets the line space on the container to the multiple provided. *******************************************************************************/ // Note that the implementors need to provide the container for this view component fluid.defaults("fluid.prefs.enactor.lineSpace", { gradeNames: ["fluid.prefs.enactor", "fluid.viewComponent"], preferenceMap: { "fluid.prefs.lineSpace": { "model.value": "default" } }, fontSizeMap: {}, // must be supplied by implementors invokers: { set: { funcName: "fluid.prefs.enactor.lineSpace.set", args: ["{arguments}.0", "{that}", "{that}.getLineHeightMultiplier"] }, getTextSizeInPx: { funcName: "fluid.prefs.enactor.getTextSizeInPx", args: ["{that}.container", "{that}.options.fontSizeMap"] }, getLineHeight: { funcName: "fluid.prefs.enactor.lineSpace.getLineHeight", args: "{that}.container" }, getLineHeightMultiplier: { funcName: "fluid.prefs.enactor.lineSpace.getLineHeightMultiplier", args: [{expander: {func: "{that}.getLineHeight"}}, {expander: {func: "{that}.getTextSizeInPx"}}] } }, modelListeners: { value: { listener: "{that}.set", args: ["{change}.value"] } } }); // Get the line-height of an element // In IE8 and IE9 this will return the line-height multiplier // In other browsers it will return the pixel value of the line height. fluid.prefs.enactor.lineSpace.getLineHeight = function (container) { return container.css("line-height"); }; // Interprets browser returned "line-height" value, either a string "normal", a number with "px" suffix or "undefined" // into a numeric value in em. // Return 0 when the given "lineHeight" argument is "undefined" (http://issues.fluidproject.org/browse/FLUID-4500). fluid.prefs.enactor.lineSpace.getLineHeightMultiplier = function (lineHeight, fontSize) { // Handle the given "lineHeight" argument is "undefined", which occurs when firefox detects // "line-height" css value on a hidden container. (http://issues.fluidproject.org/browse/FLUID-4500) if (!lineHeight) { return 0; } // Needs a better solution. For now, "line-height" value "normal" is defaulted to 1.2em // according to https://developer.mozilla.org/en/CSS/line-height if (lineHeight === "normal") { return 1.2; } // Continuing the work-around of jQuery + IE bug - http://bugs.jquery.com/ticket/2671 if (lineHeight.match(/[0-9]$/)) { return Number(lineHeight); } return Math.round(parseFloat(lineHeight) / fontSize * 100) / 100; }; fluid.prefs.enactor.lineSpace.set = function (times, that, getLineHeightMultiplierFunc) { // Calculating the initial size here rather than using a members expand because the "line-height" // cannot be detected on hidden containers such as separated paenl iframe. if (!that.initialSize) { that.initialSize = getLineHeightMultiplierFunc(); } // that.initialSize === 0 when the browser returned "lineHeight" css value is undefined, // which occurs when firefox detects "line-height" value on a hidden container. // @ See getLineHeightMultiplier() & http://issues.fluidproject.org/browse/FLUID-4500 if (that.initialSize) { var targetLineSpace = times * that.initialSize; that.container.css("line-height", targetLineSpace); } }; /******************************************************************************* * tableOfContents * * To create and show/hide table of contents *******************************************************************************/ // Note that the implementors need to provide the container for this view component fluid.defaults("fluid.prefs.enactor.tableOfContents", { gradeNames: ["fluid.prefs.enactor", "fluid.viewComponent"], preferenceMap: { "fluid.prefs.tableOfContents": { "model.toc": "default" } }, tocTemplate: null, // must be supplied by implementors components: { tableOfContents: { type: "fluid.tableOfContents", container: "{fluid.prefs.enactor.tableOfContents}.container", createOnEvent: "onCreateTOCReady", options: { components: { levels: { type: "fluid.tableOfContents.levels", options: { resources: { template: { forceCache: true, url: "{fluid.prefs.enactor.tableOfContents}.options.tocTemplate" } } } } }, listeners: { "afterRender.boilAfterTocRender": "{fluid.prefs.enactor.tableOfContents}.events.afterTocRender" } } } }, invokers: { applyToc: { funcName: "fluid.prefs.enactor.tableOfContents.applyToc", args: ["{arguments}.0", "{that}"] } }, events: { onCreateTOCReady: null, afterTocRender: null, onLateRefreshRelay: null }, modelListeners: { toc: { listener: "{that}.applyToc", args: ["{change}.value"] } }, distributeOptions: { source: "{that}.options.ignoreForToC", target: "{that tableOfContents}.options.ignoreForToC" } }); fluid.prefs.enactor.tableOfContents.applyToc = function (value, that) { if (value) { if (that.tableOfContents) { that.tableOfContents.show(); } else { that.events.onCreateTOCReady.fire(); } } else if (that.tableOfContents) { that.tableOfContents.hide(); } }; })(jQuery, fluid_2_0_0);