parent
14b241a2e0
commit
91bb501538
812 changed files with 179710 additions and 0 deletions
@ -0,0 +1,474 @@ |
||||
"use strict"; |
||||
|
||||
module.exports = { |
||||
"extends": [ |
||||
"../platform/toolkit/.eslintrc.js" |
||||
], |
||||
"rules": { |
||||
// Enforce one true brace style (opening brace on the same line)
|
||||
// Allow single line (for now) because of the vast number of changes needed
|
||||
"brace-style": [2, "1tbs", { allowSingleLine: true }], |
||||
|
||||
// Enforce newline at the end of file, with no multiple empty lines.
|
||||
"eol-last": 2, |
||||
|
||||
// Disallow using variables outside the blocks they are defined
|
||||
"block-scoped-var": 2, |
||||
|
||||
// Allow trailing commas for easy list extension. Having them does not
|
||||
// impair readability, but also not required either.
|
||||
"comma-dangle": 0, |
||||
|
||||
// Enforce spacing before and after comma
|
||||
"comma-spacing": [2, { before: false, after: true }], |
||||
|
||||
// Enforce one true comma style.
|
||||
"comma-style": [2, "last"], |
||||
|
||||
// Enforce curly brace conventions for all control statements.
|
||||
"curly": 2, |
||||
|
||||
// Enforce the spacing around the * in generator functions.
|
||||
"generator-star-spacing": [2, "after"], |
||||
|
||||
// Require space before/after arrow function's arrow
|
||||
"arrow-spacing": [2, { before: true, after: true }], |
||||
|
||||
// Enforces spacing between keys and values in object literal properties.
|
||||
"key-spacing": [2, { beforeColon: false, afterColon: true, mode: "minimum" }], |
||||
|
||||
// Disallow the omission of parentheses when invoking a constructor with no
|
||||
// arguments.
|
||||
"new-parens": 2, |
||||
|
||||
// Disallow use of the Array constructor.
|
||||
"no-array-constructor": 2, |
||||
|
||||
// disallow use of the Object constructor
|
||||
"no-new-object": 2, |
||||
|
||||
// Disallow Primitive Wrapper Instances
|
||||
"no-new-wrappers": 2, |
||||
|
||||
// Disallow the catch clause parameter name being the same as a variable in
|
||||
// the outer scope, to avoid confusion.
|
||||
"no-catch-shadow": 2, |
||||
|
||||
// Disallow assignment in conditional expressions.
|
||||
"no-cond-assign": 2, |
||||
|
||||
// Disallow use of debugger.
|
||||
"no-debugger": 2, |
||||
|
||||
// Disallow deletion of variables (deleting properties is fine).
|
||||
"no-delete-var": 2, |
||||
|
||||
// Disallow duplicate arguments in functions.
|
||||
"no-dupe-args": 2, |
||||
|
||||
// Disallow duplicate keys when creating object literals.
|
||||
"no-dupe-keys": 2, |
||||
|
||||
// Disallow a duplicate case label.
|
||||
"no-duplicate-case": 2, |
||||
|
||||
// Disallow the use of empty character classes in regular expressions.
|
||||
"no-empty-character-class": 2, |
||||
|
||||
// Disallow assigning to the exception in a catch block.
|
||||
"no-ex-assign": 2, |
||||
|
||||
// Disallow adding to native types
|
||||
"no-extend-native": 2, |
||||
|
||||
// Disallow double-negation boolean casts in a boolean context.
|
||||
"no-extra-boolean-cast": 2, |
||||
|
||||
// Disallow unnecessary semicolons.
|
||||
"no-extra-semi": 2, |
||||
|
||||
// Disallow mixed spaces and tabs for indentation.
|
||||
"no-mixed-spaces-and-tabs": 2, |
||||
|
||||
// Disallow reassignments of native objects.
|
||||
"no-native-reassign": 2, |
||||
|
||||
// Disallow nested ternary expressions, they make the code hard to read.
|
||||
"no-nested-ternary": 2, |
||||
|
||||
// Disallow use of octal literals.
|
||||
"no-octal": 2, |
||||
|
||||
// Disallow comparisons where both sides are exactly the same.
|
||||
"no-self-compare": 2, |
||||
|
||||
// Disallow sparse arrays, eg. let arr = [,,2].
|
||||
// Array destructuring is fine though:
|
||||
// for (let [, breakpointPromise] of aPromises)
|
||||
"no-sparse-arrays": 2, |
||||
|
||||
// Disallow trailing whitespace at the end of lines.
|
||||
"no-trailing-spaces": 2, |
||||
|
||||
// Disallow use of the with statement.
|
||||
"no-with": 2, |
||||
|
||||
// Disallow comparisons with the value NaN.
|
||||
"use-isnan": 2, |
||||
|
||||
// Ensure that the results of typeof are compared against a valid string.
|
||||
"valid-typeof": 2, |
||||
|
||||
// disallow the use of object properties of the global object (Math and
|
||||
// JSON) as functions
|
||||
"no-obj-calls": 2, |
||||
|
||||
// disallow use of octal escape sequences in string literals, such as
|
||||
// var foo = "Copyright \251";
|
||||
"no-octal-escape": 2, |
||||
|
||||
// disallow use of void operator
|
||||
"no-void": 2, |
||||
|
||||
// Disallow Yoda conditions (where literal value comes first).
|
||||
"yoda": 2, |
||||
|
||||
// Require a space immediately following the // in a line comment.
|
||||
"spaced-comment": [2, "always"], |
||||
|
||||
// Require use of the second argument for parseInt().
|
||||
"radix": 2, |
||||
|
||||
// Require spaces before/after unary operators (words on by default,
|
||||
// nonwords off by default).
|
||||
"space-unary-ops": [2, { words: true, nonwords: false }], |
||||
|
||||
// Enforce spacing after semicolons.
|
||||
"semi-spacing": [2, { before: false, after: true }], |
||||
|
||||
// Disallow the use of Boolean literals in conditional expressions.
|
||||
"no-unneeded-ternary": 2, |
||||
|
||||
// Disallow use of multiple spaces (sometimes used to align const values,
|
||||
// array or object items, etc.). It's hard to maintain and doesn't add that
|
||||
// much benefit.
|
||||
"no-multi-spaces": 2, |
||||
|
||||
// Require spaces around operators, except for a|0.
|
||||
// Disabled for now given eslint doesn't support default args yet
|
||||
// "space-infix-ops": [2, { "int32Hint": true }],
|
||||
|
||||
// Require a space around all keywords.
|
||||
"keyword-spacing": 2, |
||||
|
||||
// Disallow space between function identifier and application.
|
||||
"no-spaced-func": 2, |
||||
|
||||
// Disallow shadowing of names such as arguments.
|
||||
"no-shadow-restricted-names": 2, |
||||
|
||||
// Disallow use of comma operator.
|
||||
"no-sequences": 2, |
||||
|
||||
// Disallow use of assignment in return statement. It is preferable for a
|
||||
// single line of code to have only one easily predictable effect.
|
||||
"no-return-assign": 2, |
||||
|
||||
// Require return statements to either always or never specify values
|
||||
"consistent-return": 2, |
||||
|
||||
// Disallow padding within blocks.
|
||||
"padded-blocks": [2, "never"], |
||||
|
||||
// Disallow spaces inside parentheses.
|
||||
"space-in-parens": [2, "never"], |
||||
|
||||
// Require space after keyword for anonymous functions, but disallow space
|
||||
// after name of named functions.
|
||||
"space-before-function-paren": [2, { anonymous: "never", named: "never" }], |
||||
|
||||
// Disallow unreachable statements after a return, throw, continue, or break
|
||||
// statement.
|
||||
"no-unreachable": 2, |
||||
|
||||
// Always require use of semicolons wherever they are valid.
|
||||
"semi": [2, "always"], |
||||
|
||||
// Disallow empty statements. This will report an error for:
|
||||
// try { something(); } catch (e) {}
|
||||
// but will not report it for:
|
||||
// try { something(); } catch (e) { /* Silencing the error because ...*/ }
|
||||
// which is a valid use case.
|
||||
"no-empty": 2, |
||||
|
||||
// Disallow declaring the same variable more than once (we use let anyway).
|
||||
"no-redeclare": 2, |
||||
|
||||
// Warn about declaration of variables already declared in the outer scope.
|
||||
// This isn't an error because it sometimes is useful to use the same name
|
||||
// in a small helper function rather than having to come up with another
|
||||
// random name. Still, making this a warning can help people avoid being
|
||||
// confused.
|
||||
"no-shadow": 2, |
||||
|
||||
// We use var-only-at-top-level instead of no-var as we allow top level
|
||||
// vars.
|
||||
"no-var": 0, |
||||
"mozilla/var-only-at-top-level": 1, |
||||
|
||||
// Disallow global and local variables that aren't used, but allow unused function arguments.
|
||||
"no-unused-vars": [2, { vars: "all", args: "none", varsIgnorePattern: "EXPORTED_SYMBOLS" }], |
||||
|
||||
"mozilla/mark-test-function-used": 1, |
||||
|
||||
// Require padding inside curly braces
|
||||
"object-curly-spacing": [2, "always"], |
||||
|
||||
// Disallow spaces inside of brackets
|
||||
"array-bracket-spacing": [2, "never"], |
||||
|
||||
// Disallow control characters in regular expressions
|
||||
"no-control-regex": 2, |
||||
|
||||
// Disallow invalid regular expression strings in RegExp constructors
|
||||
"no-invalid-regexp": 2, |
||||
|
||||
// Disallow multiple spaces in regular expression literals
|
||||
"no-regex-spaces": 2, |
||||
|
||||
// Disallow irregular whitespace
|
||||
"no-irregular-whitespace": 2, |
||||
|
||||
// Disallow negating the left operand in `in` expressions
|
||||
"no-negated-in-lhs": 2, |
||||
|
||||
// Allow constant expressions in conditions
|
||||
// With 2.11.0 we can enable this with checkLoops: false
|
||||
"no-constant-condition": [2, { checkLoops: false }], |
||||
|
||||
// Disallow Regexs That Look Like Division
|
||||
"no-div-regex": 2, |
||||
|
||||
// Disallow Iterator (using __iterator__)
|
||||
"no-iterator": 2, |
||||
|
||||
// Enforce consistent linebreak style
|
||||
"linebreak-style": [2, "unix"], |
||||
|
||||
// Enforces return statements in callbacks of array's methods
|
||||
"array-callback-return": 2, |
||||
|
||||
// Verify super() calls in constructors
|
||||
"constructor-super": 2, |
||||
|
||||
// Disallow modifying variables of class declarations
|
||||
"no-class-assign": 2, |
||||
|
||||
// Disallow modifying variables that are declared using const
|
||||
"no-const-assign": 2, |
||||
|
||||
// Disallow duplicate name in class members
|
||||
"no-dupe-class-members": 2, |
||||
|
||||
// Disallow use of this/super before calling super() in constructors
|
||||
"no-this-before-super": 2, |
||||
|
||||
// Disallow duplicate imports
|
||||
"no-duplicate-imports": 2, |
||||
|
||||
// Disallow empty destructuring patterns
|
||||
"no-empty-pattern": 2, |
||||
|
||||
// Disallow Labeled Statements
|
||||
"no-labels": 2, |
||||
|
||||
// Disallow Multiline Strings
|
||||
"no-multi-str": 2, |
||||
|
||||
// Disallow Symbol Constructor
|
||||
"no-new-symbol": 2, |
||||
|
||||
// Disallow Initializing to undefined
|
||||
"no-undef-init": 2, |
||||
|
||||
// Disallow control flow statements in finally blocks
|
||||
"no-unsafe-finally": 2, |
||||
|
||||
// Disallow Unused Labels
|
||||
"no-unused-labels": 2, |
||||
|
||||
// Disallow unnecessary computed property keys on objects
|
||||
"no-useless-computed-key": 2, |
||||
|
||||
// Disallow unnecessary constructor
|
||||
"no-useless-constructor": 2, |
||||
|
||||
// Disallow renaming import, export, and destructured assignments to the
|
||||
// same name
|
||||
"no-useless-rename": 2, |
||||
|
||||
// Enforce spacing between rest and spread operators and their expressions
|
||||
"rest-spread-spacing": [2, "never"], |
||||
|
||||
// Disallow usage of spacing in template string expressions
|
||||
"template-curly-spacing": [2, "never"], |
||||
|
||||
// Disallow the Unicode Byte Order Mark
|
||||
"unicode-bom": [2, "never"], |
||||
|
||||
// Enforce spacing around the * in yield* expressions
|
||||
"yield-star-spacing": [2, "after"], |
||||
|
||||
// Disallow Implied eval
|
||||
"no-implied-eval": 2, |
||||
|
||||
// Disallow unnecessary function binding
|
||||
"no-extra-bind": 2, |
||||
|
||||
// Disallow new For Side Effects
|
||||
"no-new": 2, |
||||
|
||||
// Disallow Self Assignment
|
||||
"no-self-assign": 2, |
||||
|
||||
// Disallow confusing multiline expressions
|
||||
"no-unexpected-multiline": 2, |
||||
|
||||
// Require IIFEs to be Wrapped
|
||||
"wrap-iife": [2, "inside"], |
||||
|
||||
// Disallow Unused Expressions
|
||||
"no-unused-expressions": 2, |
||||
|
||||
// Disallow function or var declarations in nested blocks
|
||||
"no-inner-declarations": 2, |
||||
|
||||
// Enforce newline before and after dot
|
||||
"dot-location": [2, "property"], |
||||
|
||||
// Disallow Use of caller/callee
|
||||
"no-caller": 2, |
||||
|
||||
// Disallow Case Statement Fallthrough
|
||||
"no-fallthrough": 2, |
||||
|
||||
// Disallow Floating Decimals
|
||||
"no-floating-decimal": 2, |
||||
|
||||
// Require Space Before Blocks
|
||||
"space-before-blocks": 2, |
||||
|
||||
// Operators always before the line break
|
||||
"operator-linebreak": [2, "after", { overrides: { ":": "before", "?": "ignore" } }], |
||||
|
||||
// Restricts the use of parentheses to only where they are necessary
|
||||
// Disabled for now since this also removes parens around assignments, e.g. let foo = bar == baz
|
||||
// "no-extra-parens": [2, "all", { "conditionalAssign": false, "returnAssign": false, "nestedBinaryExpressions": false }],
|
||||
|
||||
// Double quotes should be used.
|
||||
"quotes": [2, "double", { avoidEscape: true }], |
||||
|
||||
// Disallow if as the only statement in an else block.
|
||||
"no-lonely-if": 2, |
||||
|
||||
// Not more than two empty lines with in the file, and no extra lines at
|
||||
// beginning or end of file.
|
||||
"no-multiple-empty-lines": [2, { max: 2, maxEOF: 0, maxBOF: 0 }], |
||||
|
||||
// Make sure all setters have a corresponding getter
|
||||
"accessor-pairs": 2, |
||||
|
||||
// Enforce spaces inside of single line blocks
|
||||
"block-spacing": [2, "always"], |
||||
|
||||
// Disallow spaces inside of computed properties
|
||||
"computed-property-spacing": [2, "never"], |
||||
|
||||
// Require consistent this (using |self|)
|
||||
"consistent-this": [2, "self"], |
||||
|
||||
// Disallow unnecessary .call() and .apply()
|
||||
"no-useless-call": 2, |
||||
|
||||
// Require dot notation when accessing properties
|
||||
"dot-notation": 2, |
||||
|
||||
// Disallow named function expressions
|
||||
"func-names": [2, "never"], |
||||
|
||||
// Enforce placing object properties on separate lines
|
||||
"object-property-newline": [2, { allowMultiplePropertiesPerLine: true }], |
||||
|
||||
// Enforce consistent line breaks inside braces
|
||||
"object-curly-newline": [2, { multiline: true }], |
||||
|
||||
// Disallow whitespace before properties
|
||||
"no-whitespace-before-property": 2, |
||||
|
||||
// Disallow unnecessary escape usage
|
||||
"no-useless-escape": 2, |
||||
|
||||
// Disallow mixes of different operators, but allow simple math operations.
|
||||
"no-mixed-operators": [2, { |
||||
groups: [ |
||||
/* ["+", "-", "*", "/", "%", "**"], */ |
||||
["&", "|", "^", "~", "<<", ">>", ">>>"], |
||||
["==", "!=", "===", "!==", ">", ">=", "<", "<="], |
||||
["&&", "||"], |
||||
["in", "instanceof"] |
||||
] |
||||
}], |
||||
|
||||
// Disallow unnecessary concatenation of strings
|
||||
"no-useless-concat": 2, |
||||
|
||||
// Disallow unmodified conditions of loops
|
||||
"no-unmodified-loop-condition": 2, |
||||
|
||||
// Suggest using arrow functions as callbacks
|
||||
"prefer-arrow-callback": [2, { allowNamedFunctions: true }], |
||||
|
||||
// Suggest using the spread operator instead of .apply()
|
||||
"prefer-spread": 2, |
||||
|
||||
// Quoting style for property names
|
||||
"quote-props": [2, "consistent-as-needed", { keywords: true }], |
||||
|
||||
// Disallow negated conditions
|
||||
"no-negated-condition": 2, |
||||
|
||||
// Enforce a maximum number of statements allowed per line
|
||||
"max-statements-per-line": [2, { max: 2 }], |
||||
|
||||
// Disallow arrow functions where they could be confused with comparisons
|
||||
"no-confusing-arrow": 2, |
||||
|
||||
// Disallow Unnecessary Nested Blocks
|
||||
"no-lone-blocks": 2, |
||||
|
||||
// Enforce minimum identifier length
|
||||
"id-length": [2, { |
||||
min: 3, |
||||
exceptions: [ |
||||
/* sorting */ "a", "b", |
||||
/* exceptions */ "e", "ex", |
||||
/* loop indices */ "i", "j", "k", "n", |
||||
/* coordinates */ "x", "y", |
||||
/* regexes */ "re", |
||||
/* known words */ "rc", "rv", "id", "OS", "os", "db", |
||||
/* mail/calendar words */ "to", "cc", |
||||
/* Components */ "Ci", "Cc", "Cu", "Cr", |
||||
] |
||||
}], |
||||
|
||||
// Disallow lexical declarations in case/default clauses
|
||||
"no-case-declarations": 2, |
||||
|
||||
// Enforce consistent indentation (4-space)
|
||||
"indent": [2, 4, { SwitchCase: 1 }], |
||||
|
||||
// The following rules will not be enabled currently, but are kept here for
|
||||
// easier updates in the future.
|
||||
"no-else-return": 0, |
||||
} |
||||
}; |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,289 @@ |
||||
<?xml version="1.0"?> |
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public |
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> |
||||
|
||||
<bindings id="agenda-list-bindings" |
||||
xmlns="http://www.mozilla.org/xbl" |
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" |
||||
xmlns:xbl="http://www.mozilla.org/xbl"> |
||||
|
||||
<binding id="agenda-base-richlist-item" |
||||
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> |
||||
<implementation> |
||||
<field name="mOccurrence">null</field>; |
||||
<property name="occurrence" readonly="true"> |
||||
<getter><![CDATA[ |
||||
return this.mOccurrence; |
||||
]]></getter> |
||||
</property> |
||||
</implementation> |
||||
|
||||
<handlers> |
||||
<handler event="click" phase="capturing"><![CDATA[ |
||||
if (event.detail == 1) { |
||||
agendaListbox.onSelect(this); |
||||
} else if (event.button == 0) { |
||||
// We only care about button 0 doubleclick events |
||||
document.getElementById("agenda_edit_event_command").doCommand(); |
||||
event.stopPropagation(); |
||||
event.preventDefault(); |
||||
} |
||||
]]></handler> |
||||
<handler event="mouseover"><![CDATA[ |
||||
event.stopPropagation(); |
||||
onMouseOverItem(event); |
||||
]]></handler> |
||||
</handlers> |
||||
</binding> |
||||
|
||||
<binding id="agenda-checkbox-richlist-item" |
||||
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> |
||||
<content> |
||||
<xul:treenode-checkbox class="agenda-checkbox" anonid="agenda-checkbox-widget" |
||||
flex="1" |
||||
xbl:inherits="selected,label,hidden,disabled"/> |
||||
</content> |
||||
<implementation> |
||||
<field name="kCheckbox">null</field>; |
||||
<constructor><![CDATA[ |
||||
this.kCheckbox = document.getAnonymousElementByAttribute(this, "anonid", "agenda-checkbox-widget"); |
||||
]]></constructor> |
||||
|
||||
<method name="getItem"> |
||||
<body><![CDATA[ |
||||
return this.mItem; |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="setItem"> |
||||
<parameter name="synthetic"/> |
||||
<parameter name="showsToday"/> |
||||
<body><![CDATA[ |
||||
this.mItem = synthetic; |
||||
let duration = synthetic.duration; |
||||
if (showsToday) { |
||||
this.kCheckbox.label = this.getAttribute("title"); |
||||
if (this.id == "nextweek-header") { |
||||
if (duration > 7) { |
||||
this.kCheckbox.label += " (" + unitPluralForm(duration / 7, "weeks") + ")"; |
||||
} else { |
||||
this.kCheckbox.label += " (" + unitPluralForm(duration, "days") + ")"; |
||||
} |
||||
} |
||||
} else if (synthetic.duration == 1) { |
||||
this.kCheckbox.label = getDateFormatter().formatDate(synthetic.start); |
||||
} else { |
||||
this.kCheckbox.label = getDateFormatter().formatInterval(synthetic.start, synthetic.end); |
||||
} |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="getCheckbox"> |
||||
<body><![CDATA[ |
||||
return this.kCheckbox; |
||||
]]></body> |
||||
</method> |
||||
</implementation> |
||||
</binding> |
||||
|
||||
<binding id="agenda-allday-richlist-item" |
||||
extends="chrome://calendar/content/agenda-listbox.xml#agenda-base-richlist-item"> |
||||
<content tooltip="itemTooltip"> |
||||
<xul:hbox anonid="agenda-container-box" |
||||
class="agenda-allday-container-box" |
||||
xbl:inherits="selected,disabled" |
||||
flex="1"> |
||||
<xul:vbox pack="center" flex="1"> |
||||
<xul:label anonid="agenda-allDayEvent-date" class="agenda-event-start" |
||||
crop="end" xbl:inherits="selected" hidden="true"/> |
||||
<xul:hbox flex="1" align="start"> |
||||
<xul:image anonid="agenda-multiDayEvent-image" class="agenda-multiDayEvent-image"/> |
||||
<xul:calendar-month-day-box-item anonid="allday-item" |
||||
flex="1" |
||||
flat="true"/> |
||||
</xul:hbox> |
||||
</xul:vbox> |
||||
</xul:hbox> |
||||
</content> |
||||
<implementation> |
||||
<field name="mAllDayItem">null</field>; |
||||
|
||||
<constructor><![CDATA[ |
||||
this.mAllDayItem = document.getAnonymousElementByAttribute(this, "anonid", "allday-item"); |
||||
]]></constructor> |
||||
|
||||
<method name="setOccurrence"> |
||||
<parameter name="aOccurrence"/> |
||||
<parameter name="aPeriod"/> |
||||
<body><![CDATA[ |
||||
this.mOccurrence = aOccurrence; |
||||
this.mAllDayItem.occurrence = aOccurrence; |
||||
let dateFormatter = cal.getDateFormatter(); |
||||
let periodStartDate = aPeriod.start.clone(); |
||||
periodStartDate.isDate = true; |
||||
let periodEndDate = aPeriod.end; |
||||
let startDate = this.mOccurrence[calGetStartDateProp(this.mOccurrence)] |
||||
.getInTimezone(calendarDefaultTimezone()); |
||||
let endDate = this.mOccurrence[calGetEndDateProp(this.mOccurrence)] |
||||
.getInTimezone(calendarDefaultTimezone()); |
||||
let endPreviousDay = endDate.clone(); |
||||
endPreviousDay.day--; |
||||
// Show items's date for long periods but also for "Upcoming" |
||||
// period with one day duration. |
||||
let showDate = aPeriod.multiday || aPeriod.duration > 1; |
||||
|
||||
let date = ""; |
||||
let iconType = ""; |
||||
let allDayDateLabel = document.getAnonymousElementByAttribute(this, "anonid", "agenda-allDayEvent-date"); |
||||
setBooleanAttribute(allDayDateLabel, "hidden", !showDate); |
||||
if (startDate.compare(endPreviousDay) == 0) { |
||||
// All day event one day duration. |
||||
date = dateFormatter.formatDate(startDate); |
||||
} else if (startDate.compare(periodStartDate) >= 0 && |
||||
startDate.compare(periodEndDate) <= 0) { |
||||
// All day event spanning multiple days. |
||||
iconType = "start"; |
||||
date = dateFormatter.formatDate(startDate); |
||||
} else if (endDate.compare(periodStartDate) >= 0 && |
||||
endDate.compare(periodEndDate) <= 0) { |
||||
iconType = "end"; |
||||
date = dateFormatter.formatDate(endPreviousDay); |
||||
} else { |
||||
iconType = "continue"; |
||||
hideElement(allDayDateLabel); |
||||
} |
||||
|
||||
let multiDayImage = document.getAnonymousElementByAttribute(this, "anonid", "agenda-multiDayEvent-image"); |
||||
multiDayImage.setAttribute("type", iconType); |
||||
// class wrap causes allday items to wrap its text in today-pane |
||||
let addWrap = document.getAnonymousElementByAttribute(this.mAllDayItem, "anonid", "eventbox"); |
||||
addWrap.classList.add("wrap"); |
||||
addWrap = document.getAnonymousElementByAttribute(this.mAllDayItem, "anonid", "event-detail-box"); |
||||
addWrap.classList.add("wrap"); |
||||
allDayDateLabel.value = date; |
||||
]]></body> |
||||
</method> |
||||
</implementation> |
||||
|
||||
<handlers> |
||||
<handler event="dragstart" phase="capturing"><![CDATA[ |
||||
invokeEventDragSession(this.mAllDayItem.occurrence.clone(), this); |
||||
event.stopPropagation(); |
||||
event.preventDefault(); |
||||
]]></handler> |
||||
</handlers> |
||||
</binding> |
||||
|
||||
<binding id="agenda-richlist-item" |
||||
extends="chrome://calendar/content/agenda-listbox.xml#agenda-base-richlist-item"> |
||||
<content tooltip="itemTooltip"> |
||||
<xul:hbox anonid="agenda-container-box" class="agenda-container-box" xbl:inherits="selected,disabled,current" flex="1"> |
||||
<xul:hbox> |
||||
<xul:vbox> |
||||
<xul:image anonid="agenda-calendar-image" class="agenda-calendar-image"/> |
||||
<xul:spacer flex="1"/> |
||||
</xul:vbox> |
||||
</xul:hbox> |
||||
<xul:vbox anonid="agenda-description" flex="1"> |
||||
<xul:hbox align="start"> |
||||
<xul:image anonid="agenda-multiDayEvent-image" class="agenda-multiDayEvent-image"/> |
||||
<xul:label anonid="agenda-event-start" class="agenda-event-start" crop="end" flex="1" xbl:inherits="selected"/> |
||||
</xul:hbox> |
||||
<xul:label anonid="agenda-event-title" class="agenda-event-title" crop="end" xbl:inherits="selected"/> |
||||
</xul:vbox> |
||||
</xul:hbox> |
||||
</content> |
||||
|
||||
<implementation> |
||||
<method name="setOccurrence"> |
||||
<parameter name="aItem"/> |
||||
<parameter name="aPeriod"/> |
||||
<body><![CDATA[ |
||||
this.mOccurrence = aItem; |
||||
this.setAttribute("status", aItem.status); |
||||
let dateFormatter = Components.classes["@mozilla.org/calendar/datetime-formatter;1"] |
||||
.getService(Components.interfaces.calIDateTimeFormatter); |
||||
|
||||
let periodStartDate = aPeriod.start.clone(); |
||||
periodStartDate.isDate = true; |
||||
let periodEndDate = aPeriod.end.clone(); |
||||
periodEndDate.day--; |
||||
let start = this.mOccurrence[calGetStartDateProp(this.mOccurrence)] |
||||
.getInTimezone(calendarDefaultTimezone()); |
||||
let end = this.mOccurrence[calGetEndDateProp(this.mOccurrence)] |
||||
.getInTimezone(calendarDefaultTimezone()); |
||||
let startDate = start.clone(); |
||||
startDate.isDate = true; |
||||
let endDate = end.clone(); |
||||
endDate.isDate = true; |
||||
let endAtMidnight = (end.hour == 0 && end.minute == 0); |
||||
if (endAtMidnight) { |
||||
endDate.day--; |
||||
} |
||||
// Show items's date for long periods but also for "Upcoming" |
||||
// period with one day duration. |
||||
let longFormat = aPeriod.multiday || aPeriod.duration > 1; |
||||
|
||||
let duration = ""; |
||||
let iconType = ""; |
||||
if (startDate.compare(endDate) == 0) { |
||||
// event that starts and ends in the same day, midnight included |
||||
duration = longFormat ? dateFormatter.formatDateTime(start) |
||||
: dateFormatter.formatTime(start); |
||||
} else if (startDate.compare(periodStartDate) >= 0 && |
||||
startDate.compare(periodEndDate) <= 0) { |
||||
// event spanning multiple days, start date within period |
||||
iconType = "start"; |
||||
duration = longFormat ? dateFormatter.formatDateTime(start) |
||||
: dateFormatter.formatTime(start); |
||||
} else if (endDate.compare(periodStartDate) >= 0 && |
||||
endDate.compare(periodEndDate) <= 0) { |
||||
// event spanning multiple days, end date within period |
||||
iconType = "end"; |
||||
if (endAtMidnight) { |
||||
duration = dateFormatter.formatDate(endDate) + " "; |
||||
duration = longFormat ? duration + calGetString("dateFormat", "midnight") |
||||
: calGetString("dateFormat", "midnight"); |
||||
} else { |
||||
duration = longFormat ? dateFormatter.formatDateTime(end) |
||||
: dateFormatter.formatTime(end); |
||||
} |
||||
} else { |
||||
iconType = "continue"; |
||||
} |
||||
let multiDayImage = document.getAnonymousElementByAttribute(this, "anonid", "agenda-multiDayEvent-image"); |
||||
multiDayImage.setAttribute("type", iconType); |
||||
let durationbox = document.getAnonymousElementByAttribute(this, "anonid", "agenda-event-start"); |
||||
durationbox.textContent = duration; |
||||
|
||||
// show items with time only (today & tomorrow) as one line. |
||||
if (longFormat) { |
||||
let titlebox = document.getAnonymousElementByAttribute(this, "anonid", "agenda-event-title"); |
||||
titlebox.textContent = aItem.title; |
||||
} else { |
||||
durationbox.textContent += " " + aItem.title; |
||||
} |
||||
this.refreshColor(); |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="refreshColor"> |
||||
<body><![CDATA[ |
||||
let calcolor = (this.mOccurrence && |
||||
this.mOccurrence.calendar.getProperty("color")) || |
||||
"#a8c2e1"; |
||||
|
||||
let imagebox = document.getAnonymousElementByAttribute(this, "anonid", "agenda-calendar-image"); |
||||
imagebox.setAttribute("style", "background-color: " + calcolor + ";"); |
||||
]]></body> |
||||
</method> |
||||
</implementation> |
||||
|
||||
<handlers> |
||||
<handler event="dragstart"><![CDATA[ |
||||
invokeEventDragSession(this.mOccurrence.clone(), this); |
||||
]]></handler> |
||||
</handlers> |
||||
</binding> |
||||
</bindings> |
@ -0,0 +1,924 @@ |
||||
<?xml version="1.0"?> |
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public |
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> |
||||
|
||||
<bindings id="calendar-multiday-view-bindings" |
||||
xmlns="http://www.mozilla.org/xbl" |
||||
xmlns:html="http://www.w3.org/1999/xhtml" |
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" |
||||
xmlns:xbl="http://www.mozilla.org/xbl"> |
||||
|
||||
<binding id="calendar-base-view"> |
||||
<resources> |
||||
<stylesheet src="chrome://calendar-common/skin/calendar-alarms.css"/> |
||||
</resources> |
||||
<implementation> |
||||
<field name="mWeekStartOffset">0</field> |
||||
<field name="mRangeStartDate">null</field>; |
||||
<field name="mRangeEndDate">null</field>; |
||||
<field name="mWorkdaysOnly">false</field> |
||||
<field name="mPendingRefreshJobs">null</field> |
||||
<field name="mCalendar">null</field> |
||||
<field name="mController">null</field> |
||||
<field name="mStartDate">null</field> |
||||
<field name="mEndDate">null</field> |
||||
<field name="mTasksInView">false</field> |
||||
<field name="mShowCompleted">false</field> |
||||
<field name="mDisplayDaysOff">true</field> |
||||
<field name="mDaysOffArray">[0, 6]</field> |
||||
<field name="mTimezone">null</field> |
||||
<field name="mFlashingEvents">null</field> |
||||
<field name="mSelectedItems">[]</field> |
||||
<field name="mLongWeekdayTotalPixels">-1</field> |
||||
<field name="mResizeHandler">null</field> |
||||
<field name="mDropShadowsLength">null</field> |
||||
<field name="mShadowOffset">null</field> |
||||
<field name="mDropShadows">null</field> |
||||
<field name="mMagnifyAmount">0</field> |
||||
<field name="mPixelScrollDelta">0</field> |
||||
<field name="mViewStart">null</field> |
||||
<field name="mViewEnd">null</field> |
||||
<field name="mToggleStatus">0</field> |
||||
<field name="mLog">null</field> |
||||
<field name="mToggleStatusFlag"><![CDATA[ |
||||
({ |
||||
WorkdaysOnly: 1, |
||||
TasksInView: 2, |
||||
ShowCompleted: 4, |
||||
}) |
||||
]]></field> |
||||
|
||||
<field name="mPrefObserver"><![CDATA[ |
||||
({ |
||||
calView: this, |
||||
observe: function(subj, topic, pref) { |
||||
this.calView.handlePreference(subj, topic, pref); |
||||
return; |
||||
} |
||||
}) |
||||
]]></field> |
||||
|
||||
<field name="mObserver"><![CDATA[ |
||||
// the calIObserver, calICompositeObserver, and calIAlarmServiceObserver |
||||
({ |
||||
QueryInterface: XPCOMUtils.generateQI([ |
||||
Components.interfaces.calIObserver, |
||||
Components.interfaces.calIAlarmServiceObserver, |
||||
Components.interfaces.calICompositeObserver |
||||
]), |
||||
|
||||
calView: this, |
||||
|
||||
onStartBatch: function() { |
||||
}, |
||||
onEndBatch: function() { |
||||
}, |
||||
|
||||
onLoad: function() { |
||||
this.calView.refresh(); |
||||
}, |
||||
|
||||
onAddItem: function(aItem) { |
||||
if (cal.isToDo(aItem)) { |
||||
if (!aItem.entryDate && !aItem.dueDate) { |
||||
return; |
||||
} |
||||
if (!this.calView.mTasksInView) { |
||||
return; |
||||
} |
||||
if (aItem.isCompleted && !this.calView.mShowCompleted) { |
||||
return; |
||||
} |
||||
} |
||||
|
||||
let occs = aItem.getOccurrencesBetween(this.calView.startDate, |
||||
this.calView.queryEndDate, |
||||
{}); |
||||
for (let occ of occs) { |
||||
this.calView.doAddItem(occ); |
||||
} |
||||
return; |
||||
}, |
||||
|
||||
onModifyItem: function(aNewItem, aOldItem) { |
||||
if (cal.isToDo(aNewItem) && cal.isToDo(aOldItem) && |
||||
!this.calView.mTasksInView) { |
||||
return; |
||||
} |
||||
let occs; |
||||
|
||||
if (!cal.isToDo(aOldItem) || aOldItem.entryDate || aOldItem.dueDate) { |
||||
occs = aOldItem.getOccurrencesBetween(this.calView.startDate, |
||||
this.calView.queryEndDate, |
||||
{}); |
||||
for (let occ of occs) { |
||||
this.calView.doDeleteItem(occ); |
||||
} |
||||
} |
||||
if (cal.isToDo(aNewItem)) { |
||||
if ((!aNewItem.entryDate && !aNewItem.dueDate) || !this.calView.mTasksInView) { |
||||
return; |
||||
} |
||||
if (aNewItem.isCompleted && !this.calView.mShowCompleted) { |
||||
return; |
||||
} |
||||
} |
||||
|
||||
occs = aNewItem.getOccurrencesBetween(this.calView.startDate, |
||||
this.calView.queryEndDate, |
||||
{}); |
||||
for (let occ of occs) { |
||||
this.calView.doAddItem(occ); |
||||
} |
||||
}, |
||||
|
||||
onDeleteItem: function(aItem) { |
||||
if (cal.isToDo(aItem)) { |
||||
if (!this.calView.mTasksInView) { |
||||
return; |
||||
} |
||||
if (!aItem.entryDate && !aItem.dueDate) { |
||||
return; |
||||
} |
||||
if (aItem.isCompleted && !this.calView.mShowCompleted) { |
||||
return; |
||||
} |
||||
} |
||||
|
||||
let occs = aItem.getOccurrencesBetween(this.calView.startDate, |
||||
this.calView.queryEndDate, |
||||
{}); |
||||
for (let occ of occs) { |
||||
this.calView.doDeleteItem(occ); |
||||
} |
||||
}, |
||||
|
||||
onError: function(aCalendar, aErrNo, aMessage) { }, |
||||
|
||||
onPropertyChanged: function(aCalendar, aName, aValue, aOldValue) { |
||||
switch (aName) { |
||||
case "suppressAlarms": |
||||
if (!Preferences.get("calendar.alarms.indicator.show", true) || |
||||
aCalendar.getProperty("capabilities.alarms.popup.supported") === false) { |
||||
break; |
||||
} |
||||
// else fall through |
||||
case "readOnly": |
||||
case "disabled": |
||||
// XXXvv we can be smarter about how we handle this stuff |
||||
this.calView.refresh(); |
||||
break; |
||||
} |
||||
}, |
||||
|
||||
onPropertyDeleting: function(aCalendar, aName) { |
||||
// Values are not important here yet. |
||||
this.onPropertyChanged(aCalendar, aName, null, null); |
||||
}, |
||||
|
||||
// |
||||
// calIAlarmServiceObserver stuff |
||||
// |
||||
onAlarm: function(aAlarmItem) { |
||||
this.calView.flashAlarm(aAlarmItem, false); |
||||
}, |
||||
|
||||
onRemoveAlarmsByItem: function(aItem) { |
||||
// Stop the flashing for the item. |
||||
this.calView.flashAlarm(aItem, true); |
||||
}, |
||||
|
||||
onRemoveAlarmsByCalendar: function(aCalendar) { |
||||
// Stop the flashing for all items of this calendar |
||||
for (let key in this.calView.mFlashingEvents) { |
||||
let item = this.calView.mFlashingEvents[key]; |
||||
if (item.calendar.id == aCalendar.id) { |
||||
this.calView.flashAlarm(item, true); |
||||
} |
||||
} |
||||
}, |
||||
|
||||
onAlarmsLoaded: function(aCalendar) {}, |
||||
|
||||
// |
||||
// calICompositeObserver stuff |
||||
// XXXvv we can be smarter about how we handle this stuff |
||||
// |
||||
onCalendarAdded: function(aCalendar) { |
||||
if (!aCalendar.getProperty("disabled")) { |
||||
this.calView.addItemsFromCalendar(aCalendar); |
||||
} |
||||
}, |
||||
|
||||
onCalendarRemoved: function(aCalendar) { |
||||
if (!aCalendar.getProperty("disabled")) { |
||||
this.calView.deleteItemsFromCalendar(aCalendar); |
||||
} |
||||
}, |
||||
|
||||
onDefaultCalendarChanged: function(aNewDefaultCalendar) { |
||||
// don't care, for now |
||||
} |
||||
}) |
||||
]]></field> |
||||
|
||||
<constructor><![CDATA[ |
||||
Components.utils.import("resource://gre/modules/Services.jsm"); |
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); |
||||
Components.utils.import("resource://gre/modules/Preferences.jsm"); |
||||
Components.utils.import("resource:///modules/gloda/log4moz.js"); |
||||
|
||||
const kWorkdaysCommand = "calendar_toggle_workdays_only_command"; |
||||
const kTasksInViewCommand = "calendar_toggle_tasks_in_view_command"; |
||||
const kShowCompleted = "calendar_toggle_show_completed_in_view_command"; |
||||
const kOrientation = "calendar_toggle_orientation_command"; |
||||
|
||||
this.workdaysOnly = (document.getElementById(kWorkdaysCommand) |
||||
.getAttribute("checked") == "true"); |
||||
this.tasksInView = (document.getElementById(kTasksInViewCommand) |
||||
.getAttribute("checked") == "true"); |
||||
this.rotated = (document.getElementById(kOrientation) |
||||
.getAttribute("checked") == "true"); |
||||
this.showCompleted = (document.getElementById(kShowCompleted) |
||||
.getAttribute("checked") == "true"); |
||||
|
||||
this.mTimezone = calendarDefaultTimezone(); |
||||
let alarmService = Components.classes["@mozilla.org/calendar/alarm-service;1"] |
||||
.getService(Components.interfaces.calIAlarmService); |
||||
alarmService.addObserver(this.mObserver); |
||||
this.setAttribute("type", this.type); |
||||
this.mResizeHandler = () => { |
||||
this.onResize(this); |
||||
}; |
||||
this.viewBroadcaster.addEventListener(this.getAttribute("type") + "viewresized", this.mResizeHandler, true); |
||||
// add a preference observer to monitor changes |
||||
Services.prefs.addObserver("calendar.", this.mPrefObserver, false); |
||||
this.weekStartOffset = Preferences.get("calendar.week.start", 0); |
||||
this.updateDaysOffPrefs(); |
||||
this.mPendingRefreshJobs = new Map(); |
||||
this.mLog = Log4Moz.getConfiguredLogger("calBaseView"); |
||||
this.mFlashingEvents = {}; |
||||
]]></constructor> |
||||
|
||||
<destructor><![CDATA[ |
||||
Components.utils.import("resource://gre/modules/Services.jsm"); |
||||
|
||||
if (this.mCalendar) { |
||||
this.mCalendar.removeObserver(this.mObserver); |
||||
} |
||||
let alarmService = Components.classes["@mozilla.org/calendar/alarm-service;1"] |
||||
.getService(Components.interfaces.calIAlarmService); |
||||
alarmService.removeObserver(this.mObserver); |
||||
this.viewBroadcaster.removeEventListener(this.getAttribute("type") + "viewresized", this.mResizeHandler, true); |
||||
Services.prefs.removeObserver("calendar.", this.mPrefObserver); |
||||
]]></destructor> |
||||
|
||||
<property name="type" readonly="true"> |
||||
<getter><![CDATA[ |
||||
let typelist = this.id.split("-"); |
||||
return typelist[0]; |
||||
]]></getter> |
||||
</property> |
||||
|
||||
<property name="viewBroadcaster" readonly="true" |
||||
onget="return document.getElementById('calendarviewBroadcaster')"/> |
||||
|
||||
<property name="labeldaybox" readonly="true" |
||||
onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'labeldaybox')"/> |
||||
|
||||
<property name="rotated" |
||||
onget="return (this.orient == 'horizontal')" |
||||
onset="return (this.orient = (val ? 'horizontal' : 'vertical'))"/> |
||||
<property name="supportsRotation" readonly="true" |
||||
onget="return false"/> |
||||
<property name="displayDaysOff" |
||||
onget="return this.mDisplayDaysOff;" |
||||
onset="return (this.mDisplayDaysOff = val);"/> |
||||
<property name="controller" |
||||
onget="return this.mController;" |
||||
onset="return (this.mController = val);"/> |
||||
<property name="daysOffArray" |
||||
onget="return this.mDaysOffArray;" |
||||
onset="return (this.mDaysOffArray = val);"/> |
||||
<property name="tasksInView" |
||||
onget="return this.mTasksInView;" |
||||
onset="return (this.mTasksInView = val);"/> |
||||
<property name="showCompleted" |
||||
onget="return this.mShowCompleted;" |
||||
onset="return (this.mShowCompleted = val);"/> |
||||
<property name="timezone" |
||||
onget="return this.mTimezone;" |
||||
onset="return (this.mTimezone = val);"/> |
||||
<property name="workdaysOnly" |
||||
onget="return this.mWorkdaysOnly;" |
||||
onset="return (this.mWorkdaysOnly = val);"/> |
||||
<property name="supportsWorkdaysOnly" readonly="true" |
||||
onget="return true;"/> |
||||
<property name="supportsZoom" readonly="true" |
||||
onget="return false;"/> |
||||
<property name="selectionObserver" readonly="true" |
||||
onget="return this.mSelectionObserver;"/> |
||||
<property name="startDay" readonly="true" |
||||
onget="return this.startDate;"/> |
||||
<property name="endDay" readonly="true" |
||||
onget="return this.endDate;"/> |
||||
<property name="supportDisjointDates" readonly="true" |
||||
onget="return false;"/> |
||||
<property name="hasDisjointDates" readonly="true" |
||||
onget="return false;"/> |
||||
<property name="rangeStartDate" |
||||
onget="return this.mRangeStartDate;" |
||||
onset="return (this.mRangeStartDate = val);"/> |
||||
<property name="rangeEndDate" |
||||
onget="return this.mRangeEndDate;" |
||||
onset="return (this.mRangeEndDate = val);"/> |
||||
<property name="observerID" readonly="true" |
||||
onget="return 'base-view-observer';"/> |
||||
|
||||
<property name="weekStartOffset"> |
||||
<getter><![CDATA[ |
||||
return this.mWeekStartOffset; |
||||
]]></getter> |
||||
<setter><![CDATA[ |
||||
this.mWeekStartOffset = val; |
||||
return val; |
||||
]]></setter> |
||||
</property> |
||||
|
||||
<property name="displayCalendar"> |
||||
<getter><![CDATA[ |
||||
return this.mCalendar; |
||||
]]></getter> |
||||
<setter><![CDATA[ |
||||
if (this.mCalendar) { |
||||
this.mCalendar.removeObserver(this.mObserver); |
||||
} |
||||
this.mCalendar = val; |
||||
this.mCalendar.addObserver(this.mObserver); |
||||
this.refresh(); |
||||
return val; |
||||
]]></setter> |
||||
</property> |
||||
|
||||
<property name="initialized"> |
||||
<getter><![CDATA[ |
||||
let retval; |
||||
|
||||
// Some views throw when accessing an uninitialized startDay |
||||
try { |
||||
retval = this.displayCalendar && this.startDay && |
||||
this.endDay; |
||||
} catch (ex) { |
||||
return false; |
||||
} |
||||
return retval; |
||||
]]></getter> |
||||
</property> |
||||
|
||||
<method name="goToDay"> |
||||
<parameter name="aDate"/> |
||||
<body><![CDATA[ |
||||
this.showDate(aDate); |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="getRangeDescription"> |
||||
<body><![CDATA[ |
||||
return getDateFormatter().formatInterval(this.rangeStartDate, this.rangeEndDate); |
||||
]]></body> |
||||
</method> |
||||
|
||||
<!-- This function guarantees that the |
||||
labels are clipped in the instance that the overflow occurrs, |
||||
avoiding horizontal scrollbars from showing up for a short period. --> |
||||
<method name="adjustWeekdayLength"> |
||||
<parameter name="forceShortName"/> |
||||
<body><![CDATA[ |
||||
let useShortNames = false; |
||||
let labeldayboxkids = this.labeldaybox.childNodes; |
||||
if (!labeldayboxkids || !labeldayboxkids[0]) { |
||||
useShortNames = true; |
||||
} else if (forceShortName && forceShortName === true) { |
||||
useShortNames = true; |
||||
} else { |
||||
let clientWidth = document.getAnonymousElementByAttribute(this, "anonid", "mainbox").clientWidth; |
||||
let timespacer = document.getAnonymousElementByAttribute(this, "anonid", "headertimespacer"); |
||||
if (timespacer) { |
||||
clientWidth -= timespacer.clientWidth; |
||||
} |
||||
if (this.getLongWeekdayTotalPixels() > 0.95 * clientWidth) { |
||||
useShortNames = true; |
||||
} |
||||
} |
||||
for (let i = 0; i < labeldayboxkids.length; i++) { |
||||
labeldayboxkids[i].shortWeekNames = useShortNames; |
||||
} |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="today"> |
||||
<body><![CDATA[ |
||||
let date = cal.jsDateToDateTime(new Date()).getInTimezone(this.mTimezone); |
||||
date.isDate = true; |
||||
return date; |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="isVisible"> |
||||
<body><![CDATA[ |
||||
return (this.nodeName == currentView().nodeName); |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="refresh"> |
||||
<body><![CDATA[ |
||||
if (this.isVisible()) { |
||||
this.addItemsFromCalendar(this.mCalendar); |
||||
} |
||||
]]></body> |
||||
</method> |
||||
|
||||
<!-- force refresh visible and invisible views. |
||||
This method is added because when only a preference is toggled, the start |
||||
and end date of views are unchanged, therefore those views behind the |
||||
"scene" might stay the same upon switch to them. --> |
||||
<method name="forceRefresh"> |
||||
<body><![CDATA[ |
||||
this.addItemsFromCalendar(this.mCalendar); |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="addItemsFromCalendar"> |
||||
<parameter name="aCalendar"/> |
||||
<body><![CDATA[ |
||||
let refreshJob = { |
||||
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.calIOperationListener]), |
||||
calView: this, |
||||
calendar: null, |
||||
calId: null, |
||||
operation: null, |
||||
cancelled: false, |
||||
|
||||
onOperationComplete: function(aOpCalendar, aStatus, aOperationType, aId, aDateTime) { |
||||
this.calView.mLog.info("Refresh complete of calendar " + this.calId); |
||||
if (this.calView.mPendingRefreshJobs.has(this.calId)) { |
||||
this.calView.mPendingRefreshJobs.delete(this.calId); |
||||
} |
||||
|
||||
if (!this.cancelled) { |
||||
// Fire event |
||||
this.calView.fireEvent("viewloaded", aOperationType); |
||||
} |
||||
}, |
||||
|
||||
onGetResult: function(aOpCalendar, aStatus, aItemType, aDetail, aCount, aItems) { |
||||
if (this.cancelled || !Components.isSuccessCode(aStatus)) { |
||||
return; |
||||
} |
||||
|
||||
for (let item of aItems) { |
||||
if (!cal.isToDo(item) || item.entryDate || item.dueDate) { |
||||
this.calView.doAddItem(item); |
||||
} |
||||
} |
||||
}, |
||||
|
||||
cancel: function() { |
||||
this.calView.mLog.info("Refresh cancelled for calendar " + this.calId); |
||||
this.cancelled = true; |
||||
let operation = cal.wrapInstance(this.operation, Components.interfaces.calIOperation); |
||||
if (operation && operation.isPending) { |
||||
operation.cancel(); |
||||
this.operation = null; |
||||
} |
||||
}, |
||||
|
||||
execute: function() { |
||||
if (!this.calView.startDate || !this.calView.endDate || !aCalendar) { |
||||
return; |
||||
} |
||||
|
||||
if (aCalendar.type == "composite") { |
||||
// we're refreshing from the composite calendar, so we can cancel |
||||
// all other pending refresh jobs. |
||||
this.calView.mLog.info("Refreshing composite calendar, cancelling all pending refreshes"); |
||||
this.calId = "composite"; |
||||
for (let job of this.calView.mPendingRefreshJobs.values()) { |
||||
job.cancel(); |
||||
} |
||||
this.calView.mPendingRefreshJobs.clear(); |
||||
this.calView.relayout(); |
||||
} else { |
||||
this.calId = aCalendar.id; |
||||
if (this.calView.mPendingRefreshJobs.has(this.calId)) { |
||||
this.calView.mPendingRefreshJobs.get(this.calId).cancel(); |
||||
this.calView.mPendingRefreshJobs.delete(this.calId); |
||||
} |
||||
} |
||||
this.calendar = aCalendar; |
||||
|
||||
// start our items query; for a disjoint date range |
||||
// we get all the items, and just filter out the ones we don't |
||||
// care about in addItem |
||||
let filter = this.calendar.ITEM_FILTER_CLASS_OCCURRENCES; |
||||
if (this.calView.mShowCompleted) { |
||||
filter |= this.calendar.ITEM_FILTER_COMPLETED_ALL; |
||||
} else { |
||||
filter |= this.calendar.ITEM_FILTER_COMPLETED_NO; |
||||
} |
||||
|
||||
if (this.calView.mTasksInView) { |
||||
filter |= this.calendar.ITEM_FILTER_TYPE_ALL; |
||||
} else { |
||||
filter |= this.calendar.ITEM_FILTER_TYPE_EVENT; |
||||
} |
||||
|
||||
let operation = this.calendar.getItems(filter, |
||||
0, |
||||
this.calView.startDate, |
||||
this.calView.queryEndDate, |
||||
this); |
||||
operation = cal.wrapInstance(operation, Components.interfaces.calIOperation); |
||||
if (operation && operation.isPending) { |
||||
this.operation = operation; |
||||
this.calView.mPendingRefreshJobs.set(this.calId, this); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
refreshJob.execute(); |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="deleteItemsFromCalendar"> |
||||
<parameter name="aCalendar"/> |
||||
<body><![CDATA[ |
||||
/* This method must be implemented in subclasses. */ |
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED; |
||||
]]></body> |
||||
</method> |
||||
|
||||
<!-- the end date that should be used for getItems and similar queries --> |
||||
<property name="queryEndDate" readonly="true"> |
||||
<getter><![CDATA[ |
||||
let end = this.endDate; |
||||
if (!end) { |
||||
return null; |
||||
} |
||||
end = end.clone(); |
||||
end.day += 1; |
||||
end.isDate = true; |
||||
return end; |
||||
]]></getter> |
||||
</property> |
||||
|
||||
<method name="fireEvent"> |
||||
<parameter name="aEventName"/> |
||||
<parameter name="aEventDetail"/> |
||||
<body><![CDATA[ |
||||
let event = document.createEvent("Events"); |
||||
event.initEvent(aEventName, true, false); |
||||
event.detail = aEventDetail; |
||||
this.dispatchEvent(event); |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="removeDropShadows"> |
||||
<body><![CDATA[ |
||||
let dropbox = document.getAnonymousElementByAttribute(this, "dropbox", "true"); |
||||
if (dropbox && dropbox !== undefined) { |
||||
dropbox.setAttribute("dropbox", "false"); |
||||
} |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="getLongWeekdayTotalPixels"> |
||||
<body><![CDATA[ |
||||
if (this.mLongWeekdayTotalPixels <= 0) { |
||||
let maxDayWidth = 0; |
||||
for (let label of this.labeldaybox.childNodes) { |
||||
if (label.localName && label.localName == "calendar-day-label") { |
||||
label.shortWeekNames = false; |
||||
let curPixelLength = label.getLongWeekdayPixels(); |
||||
maxDayWidth = Math.max(maxDayWidth, curPixelLength); |
||||
} |
||||
} |
||||
if (maxDayWidth > 0) { |
||||
this.mLongWeekdayTotalPixels = (maxDayWidth * this.labeldaybox.childNodes.length) + 10; |
||||
} |
||||
} |
||||
return this.mLongWeekdayTotalPixels; |
||||
]]></body> |
||||
</method> |
||||
|
||||
<!-- A preference handler which is called by the preference observer. |
||||
Can be overwritten in derived bindings. --> |
||||
<method name="handleCommonPreference"> |
||||
<parameter name="aSubject"/> |
||||
<parameter name="aTopic"/> |
||||
<parameter name="aPreference"/> |
||||
<body><![CDATA[ |
||||
// refresh view if categories seem to have changed |
||||
if (aPreference.startsWith("calendar.category.color")) { |
||||
this.refreshView(); |
||||
return; |
||||
} |
||||
switch (aPreference) { |
||||
case "calendar.week.d0sundaysoff": |
||||
case "calendar.week.d1mondaysoff": |
||||
case "calendar.week.d2tuesdaysoff": |
||||
case "calendar.week.d3wednesdaysoff": |
||||
case "calendar.week.d4thursdaysoff": |
||||
case "calendar.week.d5fridaysoff": |
||||
case "calendar.week.d6saturdaysoff": |
||||
this.updateDaysOffPrefs(); |
||||
break; |
||||
case "calendar.timezone.local": |
||||
this.timezone = calendarDefaultTimezone(); |
||||
this.refreshView(); |
||||
break; |
||||
case "calendar.alarms.indicator.show": |
||||
// Break here to ensure the view is refreshed |
||||
break; |
||||
case "calendar.week.start": |
||||
this.weekStartOffset = aSubject.getIntPref(aPreference); |
||||
break; |
||||
case "calendar.date.format": |
||||
this.refreshView(); |
||||
break; |
||||
default: |
||||
return; |
||||
} |
||||
this.refreshView(); |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="updateDaysOffPrefs"> |
||||
<body><![CDATA[ |
||||
const weekPrefix = "calendar.week."; |
||||
const prefNames = ["d0sundaysoff", "d1mondaysoff", "d2tuesdaysoff", |
||||
"d3wednesdaysoff", "d4thursdaysoff", |
||||
"d5fridaysoff", "d6saturdaysoff"]; |
||||
const defaults = ["true", "false", "false", "false", |
||||
"false", "false", "true"]; |
||||
let daysOff = []; |
||||
for (let i in prefNames) { |
||||
if (Preferences.get(weekPrefix + prefNames[i], defaults[i])) { |
||||
daysOff.push(Number(i)); |
||||
} |
||||
} |
||||
this.daysOffArray = daysOff; |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="refreshView"> |
||||
<body><![CDATA[ |
||||
if (!this.startDay || !this.endDay) { |
||||
// don't refresh if we're not initialized |
||||
return; |
||||
} |
||||
// Just refresh, the goToDay function will notice |
||||
this.goToDay(this.selectedDay); |
||||
this.forceRefresh(); |
||||
]]></body> |
||||
</method> |
||||
|
||||
<!-- Default implementations follow, these make things easier for |
||||
extensions that don't need certain features. --> |
||||
<method name="handlePreference"> |
||||
<parameter name="aSubject"/> |
||||
<parameter name="aTopic"/> |
||||
<parameter name="aPref"/> |
||||
<body><![CDATA[ |
||||
// Do nothing by default |
||||
]]></body> |
||||
</method> |
||||
<method name="setDateRange"> |
||||
<parameter name="aStartDate"/> |
||||
<parameter name="aEndDate"/> |
||||
<body><![CDATA[ |
||||
cal.navigationBar.setDateRange(aStartDate, aEndDate); |
||||
]]></body> |
||||
</method> |
||||
|
||||
<property name="selectedDay" |
||||
onget="return this.startDate" |
||||
onset="return this.startDate"/> |
||||
|
||||
<method name="getSelectedItems"> |
||||
<parameter name="aCount"/> |
||||
<body><![CDATA[ |
||||
aCount.value = this.mSelectedItems.length; |
||||
return this.mSelectedItems; |
||||
]]></body> |
||||
</method> |
||||
<method name="setSelectedItems"> |
||||
<parameter name="aCount"/> |
||||
<parameter name="aItems"/> |
||||
<body><![CDATA[ |
||||
this.mSelectedItems = aItems.concat([]); |
||||
return this.mSelectedItems; |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="getDateList"> |
||||
<parameter name="aCount"/> |
||||
<parameter name="aDates"/> |
||||
<body><![CDATA[ |
||||
let start = this.startDate.clone(); |
||||
while (start.compare(this.endDate) <= 0) { |
||||
dates.push(start); |
||||
start.day++; |
||||
} |
||||
aCount.value = dates.length; |
||||
return dates; |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="flashAlarm"> |
||||
<parameter name="aAlarmItem"/> |
||||
<parameter name="aStop"/> |
||||
<body><![CDATA[ |
||||
// Do nothing by default |
||||
]]></body> |
||||
</method> |
||||
|
||||
<method name="zoomIn"> |
||||
<parameter name="aLevel"/> |
||||
<body><![CDATA[ |
||||
]]></body> |
||||
</method> |
||||
<method name="zoomOut"> |
||||
<parameter name="aLevel"/> |
||||
<body |